home *** CD-ROM | disk | FTP | other *** search
/ Gekkan Dennou Club 142 / Gekkan Dennou Club - 2000.3 Vol. 142 (Japan).7z / Gekkan Dennou Club - 2000.3 Vol. 142 (Japan) (Track 1).bin / tools / s44play / s44p101s.lzh / cdxa.s < prev    next >
Text File  |  2000-01-24  |  90KB  |  3,529 lines

  1.     .include    doscall.mac
  2.     .include    scsiconst.equ
  3.     .include    global.mac
  4.     .include    preconv.mac
  5.  
  6. ;----------------------------------------------------------------
  7. ;CDXA(Compact Disc eXtended Architecture)
  8.  
  9. MAX_PATH_TABLE_LENGTH    equ    2048*8    ;パステーブルの最大サイズ(2048の倍数)
  10. MAX_DIRECTORY_LENGTH    equ    2048*8    ;1個のディレクトリの最大サイズ(2048の倍数)
  11. ;↑これらは本来,サイズがわかった時点で必要な領域をアロケートするべき
  12. ;(-onmemのときバッファを目一杯確保してしまうと他の領域をアロケートできなくなるので注意)
  13.  
  14. ;----------------------------------------------------------------
  15. ;----------------------------------------------------------------
  16. ;ISO9660のディレクトリ情報レコード
  17.     .offset    0
  18. iso9660_dir_len:    .ds.b    1    ;$0000    ディレクトリレコードの長さ
  19. iso9660_dir_xarlen:    .ds.b    1    ;$0001    XARの長さ
  20. iso9660_dir_pos_l:    .ds.l    1    ;$0002    セクタ番号(little-endian)
  21. iso9660_dir_pos_b:    .ds.l    1    ;$0006    セクタ番号(big-endian)
  22. iso9660_dir_len_l:    .ds.l    1    ;$000A    長さのバイト数(little-endian)
  23. iso9660_dir_len_b:    .ds.l    1    ;$000E    長さのバイト数(big-endian)
  24.                     ;ここからタイムスタンプ
  25. iso9660_dir_date:
  26. iso9660_dir_year:    .ds.b    1    ;$0012    西暦年-1900(0~255)
  27. iso9660_dir_month:    .ds.b    1    ;$0013    月(1~12)
  28. iso9660_dir_day:    .ds.b    1    ;$0014    日(1~31)
  29. iso9660_dir_hour:    .ds.b    1    ;$0015    時(0~23)
  30. iso9660_dir_time:
  31. iso9660_dir_minute:    .ds.b    1    ;$0016    分(0~59)
  32. iso9660_dir_second:    .ds.b    1    ;$0017    秒(0~60)
  33. iso9660_dir_diff:    .ds.b    1    ;$0018    偏差(15秒単位,0~95)
  34. iso9660_dir_file_flag:    .ds.b    1    ;$0019    ファイルフラグ
  35. iso9660_dir_unit_size:    .ds.b    1    ;$001A    ファイルユニットのサイズ
  36. iso9660_dir_gap_size:    .ds.b    1    ;$001B    インタリーブギャップのサイズ
  37. iso9660_dir_vol_num_l:    .ds.w    1    ;$001C    ボリュームの通し番号(little-endian)
  38. iso9660_dir_vol_num_b:    .ds.w    1    ;$001E    ボリュームの通し番号(big-endian)
  39. iso9660_dir_name_len:    .ds.b    1    ;$0020    ファイル識別子の長さ
  40. iso9660_dir_name:            ;$0021    ファイル識別子
  41. ;ここで偶数整合すること(隙間は$00で埋める)
  42. ;CD-Extraのディレクトリ情報レコードの拡張部分
  43. ;(ファイル識別子の直後の偶数整合の直後から)
  44.     .offset    0
  45.             .ds.b    6    ;$0000
  46.             .ds.b    2    ;$0006    'XA'($58,$41)
  47.             .ds.b    1    ;$0008    $00=2048bytes/sector,$01=2336bytes/sector
  48.             .ds.b    5    ;$0009
  49.     .text
  50.  
  51. ;----------------------------------------------------------------
  52. ;指定されたファイルがCDXAかどうか調べる
  53. ;    フルパスに変換する
  54. ;        fullpath
  55. ;    ドライブ番号を確認する
  56. ;    アクセスできるかどうか確認する
  57. ;        DRVCTRL
  58. ;    SCSI-IDを確認する
  59. ;        get_scsiid
  60. ;    CD-ROMドライブかどうか確認する
  61. ;        get_scsi_device_type
  62. ;    TOCを取得する
  63. ;        get_track_info
  64. ;    データトラックの先頭セクタ番号を確認する
  65. ;    データトラックの先頭+16のセクタをMode2 form1(2048bytes/sector)で読み込む
  66. ;        (density=$81,size=$0800)
  67. ;        +$0001~'CD001'(ISO9660識別子)を確認
  68. ;        +$0400~'CD-XA001'(CD-Extra識別子)を確認
  69. ;        +$0094~M型パステーブルの位置(絶対セクタ番号)を得る
  70. ;    M型パステーブルを読み込む
  71. ;    M型パステーブルを辿って目的のファイルがあるディレクトリの先頭セクタ番号を得る
  72. ;    ディレクトリセクタを読み込む
  73. ;        ディレクトリの占有セクタ数の確認方法は?
  74. ;            →ディレクトリの先頭に自分自身を指す情報があるのでそれを使う
  75. ;    ディレクトリから目的のファイルを探す
  76. ;        ファイル名の後ろに';1'が付いている場合があるので注意
  77. ;    CDXAであることを確認する
  78. ;        システム使用領域の先頭+6から3バイトが
  79. ;            $58(X),$41(A),$00 普通のファイル
  80. ;            $58(X),$41(A),$01 XAなファイル
  81. ;    ファイルの先頭セクタ番号とセクタ数を返す
  82. ;        ファイルの占有セクタ数の確認方法は?
  83. ;            →ファイルサイズが2048bytes/sector換算の値(2048の倍数)で入って
  84. ;            いるのでファイルサイズを2048で割ればセクタ数が求まる
  85. ;ファイルはMode2 form2(2336bytes/sector)で読み込むこと
  86. ;    (density=$81,size=$920)
  87. ;<a0.l:ファイル名の先頭
  88. ;>d0.l:先頭セクタ番号(絶対セクタ番号),-1=エラー
  89. ;>d1.l:セクタ数
  90.     .text
  91.     .align    4,$2048
  92. is_cdxa_file::
  93.     movem.l    d1-d7/a0-a6,-(sp)
  94.  
  95. ;フルパスに変換する
  96.     movea.l    a0,a1
  97.     lea.l    cdxa_fullpath_buffer,a0
  98.     bsr    fullpath
  99.     bmi    90f
  100.  
  101. ;ドライブ番号を確認する
  102.     moveq.l    #$1F,d7
  103.     and.b    (a0),d7            ;d7=ドライブ番号(1=A:)
  104.  
  105.   .if 0
  106. ;アクセスできるかどうか確認する
  107.     move.w    d7,-(sp)
  108.     DOS    _DRVCTRL
  109.     addq.l    #2,sp
  110.     tst.l    d0
  111.     bmi    90f            ;ドライブ番号が不正
  112.     moveq.l    #%00000010,d1
  113.     and.b    d0,d1
  114.     beq    90f            ;メディアがセットされていない
  115.     moveq.l    #%00000101,d1
  116.     and.b    d0,d1
  117.     bne    90f            ;メディアの準備ができていない
  118.   .endif
  119.  
  120. ;SCSI-IDを確認する
  121.     move.l    d7,d0
  122.     bsr    get_scsiid
  123.     bmi    90f            ;SCSIドライブではない
  124.     move.l    d0,cdxa_scsiid
  125.  
  126. ;CD-ROMドライブかどうか確認する
  127.     move.l    cdxa_scsiid,scsiid
  128.     move.l    scsiid,d0
  129.     bsr    get_scsi_device_type
  130.     bmi    90f            ;念のため
  131.     cmp.b    #SCSI_TYPE_CDROM,d0
  132.     bne    90f            ;CD-ROMドライブではない
  133.  
  134. ;CD-ROMの準備
  135.     bsr    init_cdrom
  136.     bmi    90f            ;メディアにアクセスできない
  137.  
  138. ;データトラックの先頭セクタ番号を確認する
  139.     lea.l    cdda_trkinf,a2        ;トラック情報レコード
  140.     move.l    cdda_mintrk,d0        ;先頭のトラック番号が1よりも大きかった場合に対応
  141.     subq.b    #1,d0            ;(念のため)
  142.     mulu.w    #trkinf_record_size,d0
  143.     lea.l    (a2,d0.l),a2        ;cdda_mintrkのトラック情報レコードの先頭
  144.     move.l    cdda_mintrk,d6        ;開始トラック番号
  145. 10:    tst.b    (trkinf_dattrk,a2)    ;-1=データトラック
  146.     bne    11f
  147.     lea.l    (trkinf_record_size,a2),a2
  148.     addq.b    #1,d6
  149.     cmp.l    cdda_maxtrk,d6
  150.     bls    10b
  151.     bra    90f            ;データトラックが見つからない
  152. 11:
  153.  
  154.     move.l    (trkinf_topfrm,a2),d5    ;d5=データトラックの先頭セクタ番号
  155.     move.l    d5,sector_dattrk_top
  156. ;データトラックの先頭+16のセクタをMode2 form1で読み込む
  157.     moveq.l    #16,d0
  158.     add.l    d5,d0            ;データトラックの先頭+16
  159.     moveq.l    #1,d1            ;セクタ数
  160.     lea.l    cdrom_volume_buffer,a0
  161.     bsr    read_cdrom_mode2_2048    ;基本ボリュームを読み込む
  162.     bmi    90f
  163.  
  164.   .if 0
  165.     lea.l    cdrom_volume_buffer,a0
  166.     .rept 16
  167.     moveq.l    #' ',d0
  168.     bsr    eputchar
  169.     move.b    (a0)+,d0
  170.     bsr    h2tos_eprint
  171.     .endm
  172.   .endif
  173.  
  174.     lea.l    cdrom_volume_buffer,a2    ;基本ボリュームの先頭
  175.  
  176. ;    +$0001~'CD001'(ISO9660識別子)を確認
  177.     lea.l    (0,a2),a0
  178.     cmpi.l    #$01434430,(a0)+    ;$01,'CD0'
  179.     bne    90f
  180.     cmpi.l    #$30310100,(a0)+    ;'01',$01,$00
  181.     bne    90f
  182.  
  183. ;    +$0400~'CD-XA001'(CD-Extra識別子)を確認
  184.     lea.l    ($0400,a2),a0
  185.     cmpi.l    #'CD-X',(a0)+
  186.     bne    90f
  187.     cmpi.l    #'A001',(a0)+
  188.     bne    90f
  189.  
  190. ;    +$0094~M型パステーブルの位置(絶対セクタ番号)を得る
  191.     move.l    ($0088,a2),d3        ;d3=パステーブルのサイズ
  192.     cmp.l    #MAX_PATH_TABLE_LENGTH,d3
  193.     bhi    90f            ;パステーブルが大きすぎる
  194.  
  195.     move.l    ($0094,a2),d6        ;d6=M型パステーブルの絶対セクタ番号
  196. ;M型パステーブルを読み込む
  197.     move.l    d6,d0            ;セクタ番号
  198.     move.l    d3,d1            ;パステーブルのバイト数
  199.     add.l    #2047,d1
  200.     lsr.l    #8,d1
  201.     lsr.l    #3,d1            ;セクタ数
  202.     lea.l    path_table_buffer,a0
  203.     bsr    read_cdrom_mode2_2048
  204.     bmi    90f            ;パステーブルを読み込めない
  205.     sf.b    (a0,d3.l)        ;念のためエンドコードを埋め込んでおく
  206.  
  207. ;M型パステーブルを辿って目的のファイルがあるディレクトリの先頭セクタ番号を得る
  208.     lea.l    cdxa_fullpath_buffer+3,a2    ;サブディレクトリの先頭
  209.     lea.l    path_table_buffer,a3    ;M型パステーブルの先頭
  210.     moveq.l    #1,d3            ;親ディレクトリの通し番号(ルートの親はルート)
  211.     move.l    (2,a3),d4        ;ルートディレクトリのセクタ番号
  212.     lea.l    (1+1+4+2+1+1,a3),a3    ;ルートディレクトリはスキップ
  213.     moveq.l    #2,d2            ;ディレクトリの通し番号
  214. 20:
  215. ;<d2.w:現在のディレクトリの通し番号
  216. ;<d3.w:親ディレクトリの通し番号
  217. ;<d4.l:親ディレクトリのセクタ番号
  218. ;<a3.l:ディレクトリレコードの先頭
  219.     moveq.l    #'/',d0
  220.     movea.l    a2,a0
  221.     bsr    strchr
  222.     bmi    24f            ;ディレクトリ終わり
  223.     lea.l    (1,a2,d0.l),a2        ;'/'の直後まで進めておく
  224. ;<d0.l:検索するディレクトリ名の長さ
  225. ;<a0.l:検索するディレクトリ名(エンドコードなし)
  226. 21:    moveq.l    #0,d1
  227.     move.b    (a3),d1            ;ディレクトリ名の長さ(0=終了)
  228.     beq    90f            ;ディレクトリが見つからない
  229.     cmp.b    d1,d0
  230.     bne    22f            ;ディレクトリ名の長さが一致しないのでスキップ
  231.     cmp.w    (6,a3),d3
  232.     bne    22f            ;親ディレクトリの通し番号が一致しないのでスキップ
  233.     lea.l    (8,a3),a1
  234.     bsr    strncmpi
  235.     beq    23f            ;一致した
  236. 22:    addq.w    #1,d1            ;偶数に切り上げる
  237.     and.w    #$FFFE,d1
  238.     lea.l    (8,a3,d1.l),a3        ;次のディレクトリレコードへ
  239.     addq.w    #1,d2            ;ディレクトリの通し番号
  240.     bra    21b            ;次のディレクトリレコードへ
  241.  
  242. 23:    move.w    d2,d3            ;ディレクトリの通し番号
  243.     move.l    (2,a3),d4        ;ディレクトリのセクタ番号
  244.     addq.w    #1,d1            ;ディレクトリ名の長さを偶数に切り上げる
  245.     and.w    #$FFFE,d1
  246.     lea.l    (8,a3,d1.l),a3        ;次のディレクトリレコードへ
  247.     addq.w    #1,d2            ;ディレクトリの通し番号
  248.     bra    20b
  249.  
  250. 24:
  251. ;<d4.l:ディレクトリのセクタ番号
  252. ;<a2.l:主ファイル名の先頭
  253.  
  254. ;ディレクトリセクタを読み込む
  255. ;    ディレクトリの占有セクタ数の確認方法は?
  256. ;        →ディレクトリの先頭に自分自身を指す情報があるのでそれを使う
  257.     move.l    d4,d0
  258.     moveq.l    #1,d1            ;とりあえず1セクタだけ読み込む
  259.     lea.l    directory_buffer,a0
  260.     bsr    read_cdrom_mode2_2048
  261.     bmi    90f            ;ディレクトリを読み込めない
  262.     move.l    directory_buffer+14,d1    ;ディレクトリのサイズ
  263.     cmp.l    #MAX_DIRECTORY_LENGTH,d1
  264.     bhi    90f            ;ディレクトリが大きすぎる
  265.     move.l    d4,d0
  266.     addq.l    #1,d0            ;次のディレクトリから
  267.     add.l    #2047,d1        ;ディレクトリのサイズを2048の倍数に切り上げる
  268.     lsr.l    #8,d1
  269.     lsr.l    #3,d1
  270.     subq.l    #1,d1
  271.     bls    @f            ;最初に読んだ1セクタに収まっている
  272.     lea.l    directory_buffer+2048,a0
  273.     bsr    read_cdrom_mode2_2048    ;ディレクトリの残りを読み込む
  274.     bmi    90f            ;ディレクトリを読み込めない
  275. @@:
  276.  
  277. ;ディレクトリから目的のファイルを探す
  278. ;    ファイル名の後ろに';1'が付いている場合があるので注意
  279. ;<a2.l:主ファイル名の先頭
  280.     lea.l    directory_buffer,a3
  281.     movea.l    a2,a0
  282.     bsr    strlen
  283.  
  284. ;<d0.l:ファイル名の長さ
  285. ;<a0.l:ファイル名
  286. ;<a3.l:ディレクトリレコード
  287. 30:    moveq.l    #0,d3
  288.     move.b    (a3),d3            ;ディレクトリレコードの長さ
  289.     moveq.l    #$02,d1            ;とりあえずディレクトリ属性だけ除外
  290.     and.b    (iso9660_dir_file_flag,a3),d1
  291.     bne    31f            ;ディレクトリだった
  292.     lea.l    (iso9660_dir_name_len,a3),a1    ;ファイル名の長さの位置
  293.     moveq.l    #0,d1
  294.     move.b    (a1)+,d1        ;ファイル名の長さ
  295.     cmp.b    d0,d1
  296.     blo    31f            ;ファイル名が短すぎる
  297.     bsr    strncmpi
  298.     bne    31f            ;一致しない
  299.     subq.l    #1,a1            ;最後に比較した位置の直後
  300.     tst.b    (a1)
  301.     beq    32f            ;一致しない
  302.     cmpi.b    #';',(a1)+
  303.     bne    31f            ;';1'がないので一致しない
  304.     cmpi.b    #'1',(a1)+
  305.     bne    31f            ;';1'がないので一致しない
  306.     tst.b    (a1)
  307.     beq    32f            ;';1'があって一致した
  308. 31:    adda.l    d3,a3
  309.     tst.b    (a3)
  310.     bne    30b            ;次のディレクトリレコード
  311.     bra    90f            ;ファイルが見つからない
  312.  
  313. 32:    add.w    #iso9660_dir_name+1,d1    ;ディレクトリレコードの先頭から
  314.                     ;識別子の末尾までの長さを,偶数に切り上げる
  315.     and.w    #$FFFE,d1
  316. ;<a3.l:ディレクトリレコードの先頭
  317. ;<d1.l:ディレクトリレコードの先頭から識別子の末尾までの長さを偶数に切り上げた値
  318. ;<d3.l:ディレクトリレコードの長さ
  319. ;    d3からd1を引いた値がシステム使用領域の長さ
  320.  
  321. ;CDXAであることを確認する
  322. ;    システム使用領域の先頭+6から3バイトが
  323. ;        $58(X),$41(A),$00 普通のファイル
  324. ;        $58(X),$41(A),$01 XAなファイル
  325.     move.w    d3,d0
  326.     sub.w    d1,d0
  327.     cmp.w    #9,d0
  328.     blo    90f            ;システム使用領域が短すぎる
  329.     lea.l    (6,a3,d1.l),a0        ;'XA'があるべき位置
  330.     cmp.w    #'XA',(a0)+
  331.     bne    90f            ;CDXAのファイルではない
  332.     cmpi.b    #$01,(a0)
  333.     bne    90f            ;CDXAのファイルではない
  334.  
  335. ;ファイルの先頭セクタ番号とセクタ数を返す
  336. ;    ファイルの占有セクタ数の確認方法は?
  337. ;        →ファイルサイズが2048bytes/sector換算の値(2048の倍数)で入って
  338. ;        いるのでファイルサイズを2048で割ればセクタ数が求まる
  339.     move.l    (iso9660_dir_pos_b,a3),d0    ;ファイルの先頭セクタ番号
  340.     move.l    (iso9660_dir_len_b,a3),d1    ;ファイルサイズ
  341.                     ;(2048byte/sector換算のサイズ)
  342.     add.l    #2047,d1        ;念のため2048の倍数に切り上げる
  343.     lsr.l    #8,d1
  344.     lsr.l    #3,d1            ;セクタ数
  345. 98:    addq.l    #4,sp            ;d1の元の値を捨てる
  346.     tst.l    d0
  347.     movem.l    (sp)+,d2-d7/a0-a6
  348.     rts
  349.  
  350. 99:    movem.l    (sp)+,d1-d7/a0-a6
  351.     rts
  352.  
  353. 90:    bsr    tini_cdrom
  354.     moveq.l    #-1,d0
  355.     movem.l    (sp)+,d1-d7/a0-a6
  356.     rts
  357.  
  358.     .data
  359.     .align    4
  360. cdxa_scsiid:        .dc.l    -3    ;CDXAファイルのあるCD-ROMドライブのSCSI-ID
  361.  
  362.     .bss
  363.     .align    4
  364. sector_dattrk_top:    .ds.l    1    ;データトラックの先頭セクタ番号
  365.  
  366. cdxa_fullpath_buffer:    .ds.b    256    ;フルパスに変換したファイル名
  367.     .align    4
  368. cdrom_volume_buffer:    .ds.b    2048    ;基本ボリューム
  369.     .align    4
  370. path_table_buffer:            ;M型パステーブル
  371. directory_buffer:            ;ディレクトリ
  372.   .if MAX_PATH_TABLE_LENGTH>=MAX_DIRECTORY_LENGTH
  373.     .ds.b    MAX_PATH_TABLE_LENGTH+2
  374.   .else
  375.     .ds.b    MAX_DIRECTORY_LENGTH+2
  376.   .endif
  377.  
  378. ;----------------------------------------------------------------
  379. ;CDXAをオープンする
  380. ;<current_param_ptr.l:パラメータバッファのアドレス
  381. ;>next_param_ptr.l:次のパラメータバッファのアドレス
  382. ;>d0.l:負数=エラー,0=データなし正常終了,その他=データあり
  383. ;>n-flag:mi=エラー
  384. ;>z-flag:eq=データなし正常終了
  385.     .text
  386.     .align    4,$2048
  387. open_cdxa::
  388.     movem.l    d1-d7/a0-a6,-(sp)
  389.  
  390.   .if 0
  391.     move.l    cdxa_scsiid,scsiid
  392.     bsr    init_cdrom
  393.     bmi    99f
  394.   .endif
  395.  
  396.     movea.l    current_param_ptr,a2
  397.  
  398.     lea.l    (pb_size,a2),a0
  399.     move.l    a0,next_param_ptr
  400.  
  401.     move.l    (pb_cdxa_start,a2),d0    ;CDXAファイルの先頭セクタ番号
  402.     move.l    (pb_cdxa_length,a2),d1    ;CDXAファイルのセクタ数
  403.  
  404.     move.l    d0,cdxa_cursec        ;現在のセクタ番号
  405.     move.l    d1,cdxa_rstsec        ;残りセクタ数
  406.  
  407.     move.l    (pb_trktop,a2),d4    ;開始トラック番号
  408.     bpl    @f
  409.     moveq.l    #0,d4
  410. @@:    cmp.l    #255,d4
  411.     bhi    90f            ;開始トラック番号が異常
  412.  
  413.     move.l    (pb_trkbtm,a2),d5    ;終了トラック番号
  414.     bmi    90f            ;終了トラック番号が異常
  415.     cmp.l    #255,d5
  416.     bls    @f
  417.     move.l    #255,d5
  418. @@:
  419.  
  420. ;トラックテーブルを初期化する
  421.     lea.l    cdxa_track_table,a0
  422.     moveq.l    #-1,d0
  423.     move.w    #256-1,d1
  424. 1:    move.l    d0,(a0)+        ;セクタヘッダのコピー
  425.     move.l    d0,(a0)+        ;開始セクタ番号
  426.     dbra    d1,1b
  427.  
  428. ;指定されたトラックを探す
  429.     move.l    cdxa_cursec,d2
  430.     move.l    cdxa_rstsec,d3
  431.  
  432.     cmp.l    d4,d5
  433.     blt    25f    ;パラメータの範囲はチェック済みなので開始>終了はあり得ないが,
  434.             ;トラック番号の範囲指定があって再生が終了している場合がある
  435.  
  436.     moveq.l    #32-1,d6        ;先頭から32トラック以内になければ諦める
  437. 1:
  438.     move.l    d2,d0
  439.     moveq.l    #1,d1
  440.     lea.l    cdxa_search_buffer,a0
  441.     bsr    read_cdrom_mode2_2336
  442.     bmi    90f
  443.  
  444.     cmpi.b    #$64,(2,a0)
  445.     bne    2f            ;音声トラックではない
  446.     cmp.b    (1,a0),d4
  447.     bhi    2f            ;トラック番号が小さすぎる
  448.     cmp.b    (1,a0),d5
  449.     bhs    3f            ;トラック番号が範囲内
  450. 2:    addq.l    #1,d2
  451.     subq.l    #1,d3
  452.     dbeq    d6,1b
  453.  
  454. ;指定された範囲の番号のトラックが存在しない
  455.     tst.b    (pb_done,a2)
  456.     bne    @f            ;再生済みのCDXAファイル
  457. ;未再生のCDXAファイル
  458.     lea.l    (m_cdxa_track_not_found,pc),a0
  459.     bsr    eaprintcrlf
  460.     bra    90f            ;再生できなかったのでエラー
  461. @@:
  462. ;再生済みのCDXAファイル
  463. 25:    tst.b    (pb_files,a2)
  464.     beq    98f            ;次のパラメータへ
  465.     sf.b    (pb_done,a2)
  466.     sf.b    (pb_is_cdxa,a2)        ;_NFILESに戻す
  467.     move.l    a2,next_param_ptr
  468.     bra    98f            ;ワイルドカードに含まれる次のファイルへ
  469.  
  470. 3:
  471.  
  472. ;トラックが見つかった
  473.     move.l    d2,cdxa_cursec        ;現在のセクタ番号
  474.     move.l    d3,cdxa_rstsec        ;残りセクタ数
  475.  
  476. ;    lea.l    cdxa_search_buffer,a0
  477. ;    moveq.l    #0,d4
  478.     move.b    (1,a0),d4        ;今回再生するトラック番号
  479.     move.l    d4,d0
  480.     addq.l    #1,d0
  481.     move.l    d0,(pb_trktop,a2)    ;開始トラック番号を修正する
  482.     move.l    a2,next_param_ptr    ;同じパラメータを繰り返す
  483.  
  484.     move.l    (a0),d0            ;セクタヘッダ
  485.     move.l    d0,cdxa_curhed
  486.     moveq.l    #MXA4,d6
  487.     btst.l    #0,d0
  488.     beq    @f
  489.     moveq.l    #SXA4,d6
  490. @@:
  491.     move.l    #37800,d7
  492.     btst.l    #2,d0
  493.     beq    @f
  494.     move.l    #18900,d7
  495. @@:
  496.     move.w    d6,data_format        ;データのフォーマット
  497.     move.l    d7,data_frequency    ;データのサンプリング周波数
  498.  
  499.     tst.b    silent_flag
  500.     bne    1f
  501.     lea.l    (m_cdxa_play_0,pc),a0
  502.     bsr    eprint
  503.     lea.l    cdxa_fullpath_buffer,a0
  504.     bsr    eprint
  505.     lea.l    (m_cdxa_play_1,pc),a0
  506.     bsr    eprint
  507.     move.l    d4,d0
  508.     bsr    utos_eprint
  509.     lea.l    (m_cdxa_play_2,pc),a0
  510.     bsr    eprint
  511.     move.l    cdxa_curhed,d0
  512.     bsr    h8tos_eprint
  513.     lea.l    (m_cdxa_play_3p,pc),a0
  514.     tst.b    conv_flag
  515.     beq    @f
  516.     lea.l    (m_cdxa_play_3c,pc),a0
  517. @@:    bsr    eprintcrlf
  518. 1:
  519.  
  520.     bsr    init_cdxa_tables    ;CDXAデコーダが使用するテーブルの初期化
  521.     bmi    90f
  522.  
  523.     clr.l    left1
  524.     clr.l    left2
  525.     clr.l    right1
  526.     clr.l    right2
  527.  
  528.     moveq.l    #1,d0            ;データあり
  529.     bra    99f
  530.  
  531. 98:    moveq.l    #0,d0            ;データなし正常終了
  532. 99:    movem.l    (sp)+,d1-d7/a0-a6
  533.     rts
  534.  
  535. 90:    moveq.l    #-1,d0
  536.     bra    99b
  537.  
  538. m_cdxa_play_0:        .dc.b    "CDXA ファイル `",0
  539. m_cdxa_play_1:        .dc.b    "' のトラック ",0
  540. m_cdxa_play_2:        .dc.b    ' ($',0
  541. m_cdxa_play_3p:        .dc.b    ') を再生します',0
  542. m_cdxa_play_3c:        .dc.b    ') を変換します',0
  543.  
  544. m_cdxa_track_not_found:        .dc.b    '指定されたトラックが見つかりません',0
  545.  
  546.     .bss
  547.     .align    4
  548. cdxa_cursec:    .ds.l    1        ;現在のセクタ番号
  549. cdxa_rstsec:    .ds.l    1        ;残りセクタ数
  550. cdxa_curhed:    .ds.l    1        ;現在のセクタヘッダ
  551.  
  552.     .align    4
  553. cdxa_track_table:    .ds.l    2*256
  554. cdxa_search_buffer:    .ds.b    2336
  555.  
  556. ;----------------------------------------------------------------
  557. ;CDXAから読み込む
  558. ;<a0.l:出力バッファの先頭
  559. ;<a1.l:入力バッファの先頭
  560. ;>d0.l:データのサイズ,-1=エラー
  561.     .text
  562.     .align    4,$2048
  563. read_cdxa::
  564.     movem.l    d1-d7/a0-a6,-(sp)
  565.     move.l    a0,a4            ;出力バッファの先頭
  566.     move.l    a1,a5            ;入力バッファの先頭
  567.  
  568. 20:    move.l    cdxa_rstsec,d0        ;残りセクタ数
  569.     beq    99f
  570.  
  571.     move.l    cdxa_cursec,d0        ;開始セクタ番号
  572.     move.l    buffrm,d1        ;バッファのセクタ数
  573.     move.b    read_shift_count,d4
  574.     lsr.l    d4,d1            ;セクタ数
  575.     cmp.l    cdxa_rstsec,d1
  576.     bls    @f
  577.     move.l    cdxa_rstsec,d1
  578. @@:    add.l    d1,cdxa_cursec
  579.     sub.l    d1,cdxa_rstsec
  580.     movea.l    a5,a0            ;入力バッファの先頭
  581.     bsr    read_cdrom_mode2_2336
  582.     bmi    90f
  583.  
  584.     move.w    d1,d5
  585.     mulu.w    #2336,d5        ;入力データのバイト数
  586.  
  587.     lea.l    (a5,d5.l),a2        ;入力データの末尾
  588.  
  589. ;バッファ内に該当するセクタが少なくとも1つは存在することを確認する
  590. ;(1つもないとpreconv_routineで困る)
  591.     movea.l    a5,a1            ;入力データの先頭
  592.     move.l    cdxa_curhed,d0
  593.     subq.w    #1,d1            ;入力セクタ数-1
  594.     bra    2f
  595. 1:    lea.l    (2336,a1),a1
  596. 2:    cmp.l    (a1),d0
  597.     dbeq    d1,1b
  598.     beq    3f
  599. ;該当するセクタが1つもないので続きを読み込む
  600.     tst.b    tab_aborted
  601.     bne    91f            ;TABが押された
  602.     tst.b    silent_flag
  603.     bne    20b
  604.     bsr    eputrotor
  605.     bra    20b
  606. 3:
  607.  
  608. ;a1からa2までを中間バッファにデコードしながらfmpに変換してa4へ
  609.     movea.l    a4,a0            ;出力バッファの先頭
  610. *    movea.l    a1,a1            ;入力データの先頭
  611. *    movea.l    a2,a2            ;入力データの末尾+1
  612.     movea.l    preconv_routine,a6    ;PCMデータをOPMのTLの並びに変換する
  613.     jsr    (a6)
  614.  
  615.     move.l    a0,d0            ;出力データの末尾+1
  616.     sub.l    a1,d0            ;出力データの長さ
  617.     beq    99f
  618.  
  619.     tas.b    (-1,a0)            ;エンドコードを付加する
  620.     smi.b    d1
  621.     neg.b    d1
  622.     sf.b    (a0)
  623.     move.b    d1,(1,a0)        ;0,1(末尾のデータのbit7の値)
  624.  
  625.     move.l    a1,nxttop
  626.  
  627. 99:    bsr    eclearrotor
  628.     tst.l    d0
  629.     movem.l    (sp)+,d1-d7/a0-a6
  630.     rts
  631.  
  632. 90:    moveq.l    #-1,d0
  633.     bra    99b
  634.  
  635. 91:    sf.b    tab_aborted
  636.     moveq.l    #0,d0
  637.     bra    99b
  638.  
  639. ;----------------------------------------------------------------
  640.     .text
  641.     .align    4,$2048
  642. close_cdxa::
  643.     bsr    tini_cdrom
  644.     moveq.l    #0,d0
  645.     rts
  646.  
  647. ;----------------------------------------------------------------
  648.     .text
  649.     .align    4,$2048
  650. get_restsize_cdxa::
  651.     move.l    cdxa_rstsec,d0
  652.     mulu.w    #2336,d0
  653.     rts
  654.  
  655. ;----------------------------------------------------------------
  656. ;----------------------------------------------------------------
  657. ;CDXAデータの前処理(CDXAデータをOPMのTLの並びに変換する)
  658. ;<a0.l:出力バッファの先頭
  659. ;<a1.l:入力データの先頭(該当するセクタの先頭)
  660. ;<a2.l:入力データの末尾+1
  661. ;>a0.l:出力データの末尾+1
  662. ;>a1.l:出力データの先頭
  663. ;?d1-d7/a2-a6
  664.     .text
  665.  
  666. ;ステレオ→ステレオ
  667. START_PRECONV_BUFFER    .macro    side
  668.     movem.l    d0/a0-a1,-(sp)
  669.     lea.l    cdxa2pcm_buffer,a0
  670.     move.l    cdxa2pcm_src_top_ptr,a1    ;最初なので必ず該当するセクタになっている
  671.   .if side=1
  672. ;ステレオ左
  673.     bsr    decode_cdxa_stereo_left
  674.   .else
  675. ;ステレオ右
  676.     bsr    decode_cdxa_stereo_right
  677.   .endif
  678.     lea.l    (2336,a1),a1
  679.     move.l    a1,cdxa2pcm_src_cur_ptr
  680.     movem.l    (sp)+,d0/a0-a1
  681.     lea.l    cdxa2pcm_buffer,Asrc
  682.     lea.l    (4032,Asrc),Alim
  683.     movea.l    cdxa2pcm_dst_top_ptr,Adst
  684.     .endm
  685.  
  686. LOOP_PRECONV_BUFFER    .macro    side
  687.     movem.l    d0-d1/a0-a1,-(sp)
  688.     move.l    cdxa2pcm_src_cur_ptr,a1
  689.     move.l    cdxa2pcm_src_lim_ptr,d1
  690.     move.l    cdxa_curhed,d0        ;次に該当するセクタを探す
  691.     bra    @_2
  692. @_1:
  693.     lea.l    (2336,a1),a1
  694. @_2:
  695.     cmpa.l    d1,a1
  696.     beq    @_8            ;該当するセクタがない
  697.     cmp.l    (a1),d0
  698.     bne    @_1
  699.     lea.l    cdxa2pcm_buffer,a0
  700.   .if side=1
  701. ;ステレオ左
  702.     bsr    decode_cdxa_stereo_left
  703.   .else
  704. ;ステレオ右
  705.     bsr    decode_cdxa_stereo_right
  706.   .endif
  707.     lea.l    (2336,a1),a1
  708.     move.l    a1,cdxa2pcm_src_cur_ptr
  709.     movem.l    (sp)+,d0-d1/a0-a1
  710.     lea.l    cdxa2pcm_buffer,Asrc
  711.     lea.l    (4032,Asrc),Alim
  712.     jmp    (Ajmp)
  713. @_8:
  714.     move.l    a1,cdxa2pcm_src_cur_ptr
  715.     movem.l    (sp)+,d0-d1/a0-a1
  716.     .endm
  717.  
  718. GET_DATA_1    .macro    src,dat,tmp
  719.     move.w    (src)+,dat
  720.     .endm
  721.  
  722. GET_DATA_2    .macro    src,dat,tmp
  723.     move.w    (src)+,dat
  724.     .endm
  725.  
  726.   .irp %q,LQ,HQ,SQ
  727.     .align    4,$2048
  728. preconv_sxa4_stereo_%q::
  729.     move.l    a0,cdxa2pcm_dst_top_ptr
  730.     move.l    a1,cdxa2pcm_src_top_ptr
  731.     move.l    a1,cdxa2pcm_src_cur_ptr
  732.     move.l    a2,cdxa2pcm_src_lim_ptr
  733.     PRECONV_STEREO_%q
  734.     movea.l    cdxa2pcm_dst_top_ptr,a1
  735.     rts
  736.   .endm
  737.  
  738. ;モノラル→モノラル
  739. START_PRECONV_BUFFER    .macro    side
  740.     movem.l    d0/a0-a1,-(sp)
  741.     lea.l    cdxa2pcm_buffer,a0
  742.     move.l    cdxa2pcm_src_top_ptr,a1    ;最初なので必ず該当するセクタになっている
  743.     bsr    decode_cdxa_mono
  744.     lea.l    (2336,a1),a1
  745.     move.l    a1,cdxa2pcm_src_cur_ptr
  746.     movem.l    (sp)+,d0/a0-a1
  747.     lea.l    cdxa2pcm_buffer,Asrc
  748.     lea.l    (8064,Asrc),Alim
  749.     movea.l    cdxa2pcm_dst_top_ptr,Adst
  750.     .endm
  751.  
  752. LOOP_PRECONV_BUFFER    .macro    side
  753.     movem.l    d0-d1/a0-a1,-(sp)
  754.     move.l    cdxa2pcm_src_cur_ptr,a1
  755.     move.l    cdxa2pcm_src_lim_ptr,d1
  756.     move.l    cdxa_curhed,d0        ;次に該当するセクタを探す
  757.     bra    @_2
  758. @_1:
  759.     lea.l    (2336,a1),a1
  760. @_2:
  761.     cmpa.l    d1,a1
  762.     beq    @_8            ;該当するセクタがない
  763.     cmp.l    (a1),d0
  764.     bne    @_1
  765.     lea.l    cdxa2pcm_buffer,a0
  766.     bsr    decode_cdxa_mono
  767.     lea.l    (2336,a1),a1
  768.     move.l    a1,cdxa2pcm_src_cur_ptr
  769.     movem.l    (sp)+,d0-d1/a0-a1
  770.     lea.l    cdxa2pcm_buffer,Asrc
  771.     lea.l    (8064,Asrc),Alim
  772.     jmp    (Ajmp)
  773. @_8:
  774.     move.l    a1,cdxa2pcm_src_cur_ptr
  775.     movem.l    (sp)+,d0-d1/a0-a1
  776.     .endm
  777.  
  778. GET_DATA_0    .macro    src,dat,tmp
  779.     move.w    (src)+,dat
  780.     .endm
  781.  
  782.   .irp %q,LQ,HQ,SQ
  783.     .align    4,$2048
  784. preconv_mxa4_mono_%q::
  785.     move.l    a0,cdxa2pcm_dst_top_ptr
  786.     move.l    a1,cdxa2pcm_src_top_ptr
  787.     move.l    a1,cdxa2pcm_src_cur_ptr
  788.     move.l    a2,cdxa2pcm_src_lim_ptr
  789.     PRECONV_MONO_%q
  790.     movea.l    cdxa2pcm_dst_top_ptr,a1
  791.     rts
  792.   .endm
  793.  
  794. ;ステレオ→モノラル
  795. START_PRECONV_BUFFER    .macro    side
  796.     movem.l    d0/a0-a1,-(sp)
  797.     lea.l    cdxa2pcm_buffer,a0
  798.     move.l    cdxa2pcm_src_top_ptr,a1    ;最初なので必ず該当するセクタになっている
  799.   .if 0
  800.     bsr    decode_cdxa_stereo_left
  801.     lea.l    (4032,a0),a0
  802.     bsr    decode_cdxa_stereo_right
  803.   .else
  804.     bsr    decode_cdxa_stereo_both
  805.   .endif
  806.     lea.l    (2336,a1),a1
  807.     move.l    a1,cdxa2pcm_src_cur_ptr
  808.     movem.l    (sp)+,d0/a0-a1
  809.     lea.l    cdxa2pcm_buffer,Asrc
  810.   .if 0
  811.     lea.l    (4032,Asrc),Alim    ;データは8064バイトあるが,Alimはleftの末尾を指す
  812.   .else
  813.     lea.l    (8064,Asrc),Alim
  814.   .endif
  815.     movea.l    cdxa2pcm_dst_top_ptr,Adst
  816.     .endm
  817.  
  818. LOOP_PRECONV_BUFFER    .macro    side
  819.     movem.l    d0-d1/a0-a1,-(sp)
  820.     move.l    cdxa2pcm_src_cur_ptr,a1
  821.     move.l    cdxa2pcm_src_lim_ptr,d1
  822.     move.l    cdxa_curhed,d0        ;次に該当するセクタを探す
  823.     bra    @_2
  824. @_1:
  825.     lea.l    (2336,a1),a1
  826. @_2:
  827.     cmpa.l    d1,a1
  828.     beq    @_8            ;該当するセクタがない
  829.     cmp.l    (a1),d0
  830.     bne    @_1
  831.     lea.l    cdxa2pcm_buffer,a0
  832.   .if 0
  833.     bsr    decode_cdxa_stereo_left
  834.     lea.l    (4032,a0),a0
  835.     bsr    decode_cdxa_stereo_right
  836.   .else
  837.     bsr    decode_cdxa_stereo_both
  838.   .endif
  839.     lea.l    (2336,a1),a1
  840.     move.l    a1,cdxa2pcm_src_cur_ptr
  841.     movem.l    (sp)+,d0-d1/a0-a1
  842.     lea.l    cdxa2pcm_buffer,Asrc
  843.   .if 0
  844.     lea.l    (4032,Asrc),Alim    ;データは8064バイトあるが,Alimはleftの末尾を指す
  845.   .else
  846.     lea.l    (8064,Asrc),Alim
  847.   .endif
  848.     jmp    (Ajmp)
  849. @_8:
  850.     move.l    a1,cdxa2pcm_src_cur_ptr
  851.     movem.l    (sp)+,d0-d1/a0-a1
  852.     .endm
  853.  
  854. GET_DATA_0    .macro    src,dat,tmp
  855.   .if 0
  856.     move.w    (4032,src),dat        ;right
  857.     add.w    (src)+,dat        ;+left
  858.   .else
  859.     move.w    (src)+,dat        ;left
  860.     add.w    (src)+,dat        ;+right
  861.   .endif
  862.     bvc    @skip
  863. @over:
  864.     roxr.w    #1,dat            ;常にvc
  865.     bra    @done
  866. @skip:
  867.     asr.w    #1,dat            ;常にvc
  868. @done:
  869.     .endm
  870.  
  871.   .irp %q,LQ,HQ,SQ
  872.     .align    4,$2048
  873. preconv_sxa4_mono_%q::
  874.     move.l    a0,cdxa2pcm_dst_top_ptr
  875.     move.l    a1,cdxa2pcm_src_top_ptr
  876.     move.l    a1,cdxa2pcm_src_cur_ptr
  877.     move.l    a2,cdxa2pcm_src_lim_ptr
  878.     PRECONV_MONO_%q
  879.     movea.l    cdxa2pcm_dst_top_ptr,a1
  880.     rts
  881.   .endm
  882.  
  883.     .bss
  884.     .align    4
  885. cdxa2pcm_dst_top_ptr:    .ds.l    1
  886. cdxa2pcm_src_top_ptr:    .ds.l    1
  887. cdxa2pcm_src_cur_ptr:    .ds.l    1
  888. cdxa2pcm_src_lim_ptr:    .ds.l    1
  889. cdxa2pcm_buffer:    .ds.b    8064
  890.  
  891. ;----------------------------------------------------------------
  892. ;----------------------------------------------------------------
  893. ;PlayStationのCDXAファイル(.XA/.STR)の音声セクタのフォーマット
  894. ;    参考:    xa2wave.c v1.2 (佐藤正徳氏作)
  895. ;        xa2pcm.x v0.6 (ハリケーン氏作)
  896. ;
  897. ;    CDXAファイルのセクタをYellowBook Mode2(2336bytes/sector)で読み込む
  898. ;
  899. ;    Sector
  900. ;        .ds.b    4    ;Header
  901. ;        .ds.b    4    ;Header
  902. ;        .ds.b    128*18    ;SoundGroup(g) g=0~17
  903. ;        .ds.b    24    ;あまり
  904. ;            (2336bytes)
  905. ;
  906. ;    Header
  907. ;        .ds.b    1    ;(Track内)Index
  908. ;        .ds.b    1    ;Track
  909. ;        .ds.b    1    ;DataType
  910. ;        .ds.b    1    ;Mode
  911. ;
  912. ;    (Track内)Index
  913. ;        ほとんど$01
  914. ;
  915. ;    Track
  916. ;        .STRの音声トラックは$01,データによっては複数のトラックが存在する
  917. ;
  918. ;    DataType
  919. ;        $42,$48など    画像
  920. ;        $64        音声
  921. ;
  922. ;    Mode
  923. ;        DataType=$64(音声)のとき
  924. ;            bit0        0=Mono,1=Stereo
  925. ;            bit2        0=37800Hz,1=18900Hz
  926. ;
  927. ;    SoundGroup(g) g=0~17
  928. ;        .ds.b    1*4    ;Unit(g,u)の(Filter(g,u)<<4)+Range(g,u) u=0~3
  929. ;        .ds.b    1*4    ;Unit(g,u)の(Filter(g,u)<<4)+Range(g,u) u=0~3
  930. ;        .ds.b    1*4    ;Unit(g,u)の(Filter(g,u)<<4)+Range(g,u) u=4~7
  931. ;        .ds.b    1*4    ;Unit(g,u)の(Filter(g,u)<<4)+Range(g,u) u=4~7
  932. ;        .ds.b    4*28    ;Sample(g,s) s=0~27
  933. ;            (128bytes)
  934. ;
  935. ;    Filter(g,u) g=0~17,u=0~7
  936. ;        0~3
  937. ;
  938. ;    Range(g,u) g=0~17,u=0~7
  939. ;        0~12
  940. ;
  941. ;    Sample(g,s) g=0~17,s=0~27
  942. ;        .ds.b    1*4    ;(Unit(g,2n+1)のData(g,2n+1,s)<<4)+Unit(g,2n)のData(g,2n,s)
  943. ;                                    n=0~3
  944. ;            (4bytes)
  945. ;
  946. ;    Data(g,u,s) g=0~17,u=0~7,s=0~27
  947. ;        0    0
  948. ;        1    1
  949. ;        2    2
  950. ;        3    3
  951. ;        4    4
  952. ;        5    5
  953. ;        6    6
  954. ;        7    7
  955. ;        8    -8
  956. ;        9    -7
  957. ;        10    -6
  958. ;        11    -5
  959. ;        12    -4
  960. ;        13    -3
  961. ;        14    -2
  962. ;        15    -1
  963. ;
  964. ;    C1(f) f=0~3
  965. ;        C1(0)=0.0    ($0000.0000)
  966. ;        C1(1)=0.9375    ($0000.F000)
  967. ;        C1(2)=1.796875    ($0001.CC00)
  968. ;        C1(3)=1.53125    ($0001.8800)
  969. ;
  970. ;    C2(f) f=0~3
  971. ;        C2(0)=0.0    ($0000.0000)
  972. ;        C2(1)=0.0    ($0000.0000)
  973. ;        C2(2)=-0.8125    ($FFFF.3000)
  974. ;        C2(3)=-0.859375    ($FFFF.2400)
  975. ;
  976. ;    デコードアルゴリズム
  977. ;
  978. ;    モノラルの場合
  979. ;        n=0
  980. ;        p(-2)=前回のp(4030)(初回は0)
  981. ;        p(-1)=前回のp(4031)(初回は0)
  982. ;        g=0~17
  983. ;            u=0~7
  984. ;                r=Range(g,u)
  985. ;                f=Filter(g,u)
  986. ;                s=0~27
  987. ;                    d=Data(g,u,s)
  988. ;                    if d>=8 then d=d-16
  989. ;                    p(n)=(d<<(12-r))+p(n-1)*C1(f)+p(n-2)*C2(f)
  990. ;                    n=n+1
  991. ;        p(0~4031)を-32768~32767にクリッピングして整数化して出力する
  992. ;
  993. ;    ステレオの場合(偶数Unitがleft,奇数Unitがright)
  994. ;        n=0
  995. ;        pl(-2)=前回のpl(2014)(初回は0)
  996. ;        pl(-1)=前回のpl(2015)(初回は0)
  997. ;        pr(-2)=前回のpr(2014)(初回は0)
  998. ;        pr(-1)=前回のpr(2015)(初回は0)
  999. ;        g=0~17
  1000. ;            u=0,2,4,6
  1001. ;                r=Range(g,u)
  1002. ;                f=Filter(g,u)
  1003. ;                s=0~27
  1004. ;                    d=Data(g,u,s)
  1005. ;                    if d>=8 then d=d-16
  1006. ;                    pl(n)=(d<<(12-r))+pl(n-1)*C1(f)+pl(n-2)*C2(f)
  1007. ;                    n=n+1
  1008. ;            u=1,3,5,7
  1009. ;                r=Range(g,u)
  1010. ;                f=Filter(g,u)
  1011. ;                s=0~27
  1012. ;                    d=Data(g,u,s)
  1013. ;                    if d>=8 then d=d-16
  1014. ;                    pr(n)=(d<<(12-r))+pr(n-1)*C1(f)+pr(n-2)*C2(f)
  1015. ;                    n=n+1
  1016. ;        pl(0~2015)がleft,pr(0~2015)がright
  1017. ;        それぞれ-32768~32767にクリッピングして整数化して出力する
  1018.  
  1019. ;----------------------------------------------------------------
  1020. ;----------------------------------------------------------------
  1021. ;CDXAデコーダが使用するテーブルの初期化
  1022. ;    偶数Unit用Rangeテーブル        2*256*13
  1023. ;    奇数Unit用Rangeテーブル        2*256*13
  1024. ;    高精度偶数Unit用Rangeテーブル    4*256*13
  1025. ;    高精度奇数Unit用Rangeテーブル    4*256*13
  1026. ;    C1(1)/2テーブル            2*32768
  1027. ;    C1(2)/2テーブル            2*32768
  1028. ;    C1(3)/2テーブル            2*32768
  1029. ;    C2(2)/2テーブル            2*32768
  1030. ;    C2(3)/2テーブル            2*32768
  1031. ;    モノラル偶数Unit用Filterテーブル    16*256
  1032. ;    モノラル奇数Unit用Filterテーブル    16*256
  1033. ;    ステレオ偶数Unit(left)用Filterテーブル    16*256
  1034. ;    ステレオ奇数Unit(right)用Filterテーブル    16*256
  1035. ;    高精度モノラル偶数Unit用Filterテーブル        8*256
  1036. ;    高精度モノラル奇数Unit用Filterテーブル        8*256
  1037. ;    高精度ステレオ偶数Unit(left)用Filterテーブル    8*256
  1038. ;    高精度ステレオ奇数Unit(right)用Filterテーブル    8*256
  1039.     .text
  1040.     .align    4,$2048
  1041. init_cdxa_tables:
  1042.     movem.l    d1-d7/a0-a6,-(sp)
  1043.     tst.b    cdxa_tables_constructed
  1044.     bne    98f
  1045.     st.b    cdxa_tables_constructed
  1046.     move.l    #(2*256*13)*2+(4*256*13)*2+(2*32768)*5+(16*256)*4+(8*256)*4,-(sp)
  1047.     DOS    _MALLOC
  1048.     addq.l    #4,sp
  1049.     tst.l    d0
  1050.     bmi    90f            ;メモリが確保できない
  1051.     movea.l    d0,a0
  1052. ;----------------------------------------------------------------
  1053. ;----------------------------------------------------------------
  1054. ;偶数Unit用Rangeテーブルを作る
  1055. ;    データの順序は
  1056. ;        Range(11~-1)
  1057. ;            上位4bit(0~15)
  1058. ;                下位4bit(0~15)
  1059. ;    設定の順序は
  1060. ;        下位4bit(0~15) +2
  1061. ;            Range(11~-1) +2*256
  1062. ;                上位4bit(0~15) +2*16
  1063. ;<a0.l:バッファの先頭アドレス(align4)
  1064. ;    2*256*13=6656bytes
  1065.     move.l    a0,even_range_table_ptr
  1066.     clr.w    d1
  1067. 1:    move.w    d1,d0
  1068.     moveq.l    #13-1,d2
  1069. 2:    asr.w    #1,d0
  1070.   .irp n,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
  1071.     move.w    d0,(2*16*n,a0)
  1072.   .endm
  1073.     lea.l    (2*256,a0),a0
  1074.     dbra    d2,2b
  1075.     lea.l    (-2*256*13+2,a0),a0
  1076.     add.w    #1<<12,d1
  1077.     bcc    1b
  1078.     lea.l    (-2*16+2*256*13,a0),a0
  1079. ;----------------------------------------------------------------
  1080. ;奇数Unit用Rangeテーブルを作る
  1081. ;    データの順序は
  1082. ;        Range(11~-1)
  1083. ;            上位4bit(0~15)
  1084. ;                下位4bit(0~15)
  1085. ;    設定の順序は
  1086. ;        上位4bit(0~15) +2*16
  1087. ;            Range(11~-1) +2*256
  1088. ;                下位4bit(0~15) +2
  1089. ;<a0.l:バッファの先頭アドレス(align4)
  1090. ;    2*256*13=6656bytes
  1091.     move.l    a0,odd_range_table_ptr
  1092.     clr.w    d1
  1093. 1:    move.w    d1,d0
  1094.     moveq.l    #13-1,d2
  1095. 2:    asr.w    #1,d0
  1096.   .irp n,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
  1097.     move.w    d0,(2*n,a0)
  1098.   .endm
  1099.     lea.l    (2*256,a0),a0
  1100.     dbra    d2,2b
  1101.     lea.l    (-2*256*13+2*16,a0),a0
  1102.     add.w    #1<<12,d1
  1103.     bcc    1b
  1104.     lea.l    (-2*256+2*256*13,a0),a0
  1105. ;----------------------------------------------------------------
  1106. ;高精度偶数Unit用Rangeテーブルを作る
  1107. ;    データの順序は
  1108. ;        Range(12~0)
  1109. ;            上位4bit(0~15)
  1110. ;                下位4bit(0~15)
  1111. ;    設定の順序は
  1112. ;        下位4bit(0~15) +4
  1113. ;            Range(12~0) +4*256
  1114. ;                上位4bit(0~15) +4*16
  1115. ;<a0.l:バッファの先頭アドレス(align4)
  1116. ;    4*256*13=13312bytes
  1117.     move.l    a0,hq_even_range_table_ptr
  1118.     moveq.l    #0,d1
  1119. 1:    move.l    d1,d0
  1120.   .if 1
  1121.     asr.l    #2,d0
  1122.   .else
  1123.     asr.l    #8,d0
  1124.   .endif
  1125.     moveq.l    #13-1,d2
  1126. 2:
  1127.   .irp n,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
  1128.     move.l    d0,(4*16*n,a0)
  1129.   .endm
  1130.     asr.l    #1,d0
  1131.     lea.l    (4*256,a0),a0
  1132.     dbra    d2,2b
  1133.     lea.l    (-4*256*13+4,a0),a0
  1134.     add.l    #1<<(12+16),d1
  1135.     bcc    1b
  1136.     lea.l    (-4*16+4*256*13,a0),a0
  1137. ;----------------------------------------------------------------
  1138. ;高精度奇数Unit用Rangeテーブルを作る
  1139. ;    データの順序は
  1140. ;        Range(12~0)
  1141. ;            上位4bit(0~15)
  1142. ;                下位4bit(0~15)
  1143. ;    設定の順序は
  1144. ;        上位4bit(0~15) +4*16
  1145. ;            Range(12~0) +4*256
  1146. ;                下位4bit(0~15) +4
  1147. ;<a0.l:バッファの先頭アドレス(align4)
  1148. ;    4*256*13=13312bytes
  1149.     move.l    a0,hq_odd_range_table_ptr
  1150.     moveq.l    #0,d1
  1151. 1:    move.l    d1,d0
  1152.   .if 1
  1153.     asr.l    #2,d0
  1154.   .else
  1155.     asr.l    #8,d0
  1156.   .endif
  1157.     moveq.l    #13-1,d2
  1158. 2:
  1159.   .irp n,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
  1160.     move.l    d0,(4*n,a0)
  1161.   .endm
  1162.     asr.l    #1,d0
  1163.     lea.l    (4*256,a0),a0
  1164.     dbra    d2,2b
  1165.     lea.l    (-4*256*13+4*16,a0),a0
  1166.     add.l    #1<<(12+16),d1
  1167.     bcc    1b
  1168.     lea.l    (-4*256+4*256*13,a0),a0
  1169. ;----------------------------------------------------------------
  1170. ;----------------------------------------------------------------
  1171.     movea.w    #$7FFF,a1        ;a1=$00007FFF(正の値に加えて5捨6入するのに使う)
  1172.     lea.l    (1,a1),a2        ;a2=$00008000(負の値に加えて5捨6入するのに使う)
  1173. ;----------------------------------------------------------------
  1174. ;C1(1)/2テーブルを作る
  1175. ;    C1(1)=0.9375    ($0000.F000)
  1176. ;    p1*C1(1)/2 p1=-32768~32766(even)
  1177. ;<a0.l:バッファの先頭アドレス(align4)
  1178. ;    2*32768=65536bytes
  1179. ;<a1.l:$00007FFF(正の値に加えて5捨6入するのに使う)
  1180. ;<a2.l:$00008000(負の値に加えて5捨6入するのに使う)
  1181.     move.l    #$0000F000,d3        ;$0000.F000/2*2=$0000.F000
  1182.     move.l    #$C4000000,d2        ;-32768*$0000.F000/2=$FFFFC400
  1183.     move.w    #16384/2-1,d4        ;-32768~-2(even)
  1184. 4:    move.l    d2,d0
  1185.     add.l    d3,d2
  1186.     add.l    a2,d0            ;絶対値を5捨6入
  1187.     move.l    d2,d1
  1188.     add.l    d3,d2
  1189.     add.l    a2,d1            ;絶対値を5捨6入
  1190.     swap.w    d1
  1191.     move.w    d1,d0
  1192.     move.l    d0,(a0)+
  1193.     dbra    d4,4b
  1194.     move.l    a0,c1_1_table_base_ptr
  1195.     move.w    #16384/2-1,d4        ;0~32766(even)
  1196. 4:    move.l    d2,d0
  1197.     add.l    d3,d2
  1198.     add.l    a1,d0            ;絶対値を5捨6入
  1199.     move.l    d2,d1
  1200.     add.l    d3,d2
  1201.     add.l    a1,d1            ;絶対値を5捨6入
  1202.     swap.w    d1
  1203.     move.w    d1,d0
  1204.     move.l    d0,(a0)+
  1205.     dbra    d4,4b
  1206. ;----------------------------------------------------------------
  1207. ;C1(2)/2テーブルを作る
  1208. ;    C1(2)=1.796875    ($0001.CC00)
  1209. ;    p1*C1(2)/2 p1=-32768~32766(even)
  1210. ;<a0.l:バッファの先頭アドレス(align4)
  1211. ;    2*32768=65536bytes
  1212. ;<a1.l:$00007FFF(正の値に加えて5捨6入するのに使う)
  1213. ;<a2.l:$00008000(負の値に加えて5捨6入するのに使う)
  1214.     move.l    #$0001CC00,d3        ;$0001.CC00/2*2=$0001.CC00
  1215.     move.l    #$8D000000,d2        ;-32768*$0001.CC00/2=$FFFF8D00
  1216.     move.w    #16384/2-1,d4        ;-32768~-2(even)
  1217. 4:    move.l    d2,d0
  1218.     add.l    d3,d2
  1219.     add.l    a2,d0            ;絶対値を5捨6入
  1220.     move.l    d2,d1
  1221.     add.l    d3,d2
  1222.     add.l    a2,d1            ;絶対値を5捨6入
  1223.     swap.w    d1
  1224.     move.w    d1,d0
  1225.     move.l    d0,(a0)+
  1226.     dbra    d4,4b
  1227.     move.l    a0,c1_2_table_base_ptr
  1228.     move.w    #16384/2-1,d4        ;0~32766(even)
  1229. 4:    move.l    d2,d0
  1230.     add.l    d3,d2
  1231.     add.l    a1,d0            ;絶対値を5捨6入
  1232.     move.l    d2,d1
  1233.     add.l    d3,d2
  1234.     add.l    a1,d1            ;絶対値を5捨6入
  1235.     swap.w    d1
  1236.     move.w    d1,d0
  1237.     move.l    d0,(a0)+
  1238.     dbra    d4,4b
  1239. ;----------------------------------------------------------------
  1240. ;C1(3)/2テーブルを作る
  1241. ;    C1(3)=1.53125    ($0001.8800)
  1242. ;    p1*C1(3)/2 p1=-32768~32766(even)
  1243. ;<a0.l:バッファの先頭アドレス(align4)
  1244. ;    2*32768=65536bytes
  1245. ;<a1.l:$00007FFF(正の値に加えて5捨6入するのに使う)
  1246. ;<a2.l:$00008000(負の値に加えて5捨6入するのに使う)
  1247.     movea.w    #$7FFF,a1
  1248.     move.l    #$00018800,d3        ;$0001.8800/2*2=$0001.8800
  1249.     move.l    #$9E000000,d2        ;-32768*$0001.8800/2=$FFFF9E00
  1250.     move.w    #16384/2-1,d4        ;-32768~-2(even)
  1251. 4:    move.l    d2,d0
  1252.     add.l    d3,d2
  1253.     add.l    a2,d0            ;絶対値を5捨6入
  1254.     move.l    d2,d1
  1255.     add.l    d3,d2
  1256.     add.l    a2,d1            ;絶対値を5捨6入
  1257.     swap.w    d1
  1258.     move.w    d1,d0
  1259.     move.l    d0,(a0)+
  1260.     dbra    d4,4b
  1261.     move.l    a0,c1_3_table_base_ptr
  1262.     move.w    #16384/2-1,d4        ;0~32766(even)
  1263. 4:    move.l    d2,d0
  1264.     add.l    d3,d2
  1265.     add.l    a1,d0            ;絶対値を5捨6入
  1266.     move.l    d2,d1
  1267.     add.l    d3,d2
  1268.     add.l    a1,d1            ;絶対値を5捨6入
  1269.     swap.w    d1
  1270.     move.w    d1,d0
  1271.     move.l    d0,(a0)+
  1272.     dbra    d4,4b
  1273. ;----------------------------------------------------------------
  1274. ;C2(2)/2テーブルを作る
  1275. ;    C2(2)=-0.8125    ($FFFF.3000)
  1276. ;    p2*C2(2)/2 p2=-32768~32766(even)
  1277. ;<a0.l:バッファの先頭アドレス(align4)
  1278. ;    2*32768=65536bytes
  1279. ;<a1.l:$00007FFF(正の値に加えて5捨6入するのに使う)
  1280. ;<a2.l:$00008000(負の値に加えて5捨6入するのに使う)
  1281.     movea.w    #$7FFF,a1
  1282.     move.l    #$FFFF3000,d3        ;$FFFF.3000/2*2=$FFFF.3000
  1283.     move.l    #$34000000,d2        ;-32768*$FFFF.3000/2=$0000.3400
  1284.     move.w    #16384/2-1,d4        ;-32768~-2(even)
  1285. 4:    move.l    d2,d0
  1286.     add.l    d3,d2
  1287.     add.l    a1,d0            ;絶対値を5捨6入
  1288.     move.l    d2,d1
  1289.     add.l    d3,d2
  1290.     add.l    a1,d1            ;絶対値を5捨6入
  1291.     swap.w    d1
  1292.     move.w    d1,d0
  1293.     move.l    d0,(a0)+
  1294.     dbra    d4,4b
  1295.     move.l    a0,c2_2_table_base_ptr
  1296.     move.l    d2,d0            ;0
  1297.     add.l    d3,d2
  1298.     add.l    a1,d0            ;絶対値を5捨6入
  1299.     move.l    d2,d1            ;2
  1300.     add.l    d3,d2
  1301.     add.l    a2,d1            ;絶対値を5捨6入
  1302.     swap.w    d1
  1303.     move.w    d1,d0
  1304.     move.l    d0,(a0)+
  1305.     move.w    #16382/2-1,d4        ;4~32766
  1306. 4:    move.l    d2,d0
  1307.     add.l    d3,d2
  1308.     add.l    a2,d0            ;絶対値を5捨6入
  1309.     move.l    d2,d1
  1310.     add.l    d3,d2
  1311.     add.l    a2,d1            ;絶対値を5捨6入
  1312.     swap.w    d1
  1313.     move.w    d1,d0
  1314.     move.l    d0,(a0)+
  1315.     dbra    d4,4b
  1316. ;----------------------------------------------------------------
  1317. ;C2(3)/2テーブルを作る
  1318. ;    C2(3)=-0.859375    ($FFFF.2400)
  1319. ;    p2*C2(3)/2 p2=-32768~32766(even)
  1320. ;<a0.l:バッファの先頭アドレス(align4)
  1321. ;    2*32768=65536bytes
  1322. ;<a1.l:$00007FFF(正の値に加えて5捨6入するのに使う)
  1323. ;<a2.l:$00008000(負の値に加えて5捨6入するのに使う)
  1324.     movea.w    #$7FFF,a1
  1325.     move.l    #$FFFF2400,d3        ;$FFFF.2400/2*2=$FFFF.2400
  1326.     move.l    #$37000000,d2        ;-32768*$FFFF.2400/2=$0000.3700
  1327.     move.w    #16384/2-1,d4        ;-32768~2(even)
  1328. 4:    move.l    d2,d0
  1329.     add.l    d3,d2
  1330.     add.l    a1,d0            ;絶対値を5捨6入
  1331.     move.l    d2,d1
  1332.     add.l    d3,d2
  1333.     add.l    a1,d1            ;絶対値を5捨6入
  1334.     swap.w    d1
  1335.     move.w    d1,d0
  1336.     move.l    d0,(a0)+
  1337.     dbra    d4,4b
  1338.     move.l    a0,c2_3_table_base_ptr
  1339.     move.l    d2,d0            ;0
  1340.     add.l    d3,d2
  1341.     add.l    a1,d0            ;絶対値を5捨6入
  1342.     move.l    d2,d1            ;2
  1343.     add.l    d3,d2
  1344.     add.l    a2,d1            ;絶対値を5捨6入
  1345.     swap.w    d1
  1346.     move.w    d1,d0
  1347.     move.l    d0,(a0)+
  1348.     move.w    #16382/2-1,d4        ;4~32766
  1349. 4:    move.l    d2,d0
  1350.     add.l    d3,d2
  1351.     add.l    a2,d0            ;絶対値を5捨6入
  1352.     move.l    d2,d1
  1353.     add.l    d3,d2
  1354.     add.l    a2,d1            ;絶対値を5捨6入
  1355.     swap.w    d1
  1356.     move.w    d1,d0
  1357.     move.l    d0,(a0)+
  1358.     dbra    d4,4b
  1359. ;----------------------------------------------------------------
  1360. ;----------------------------------------------------------------
  1361. ;モノラル偶数Unit用Filterテーブルを作る
  1362. ;    データの順序は
  1363. ;        Filter(0~3,4~15は無効)
  1364. ;            Range(0~12,13~15は無効)
  1365. ;                Rangeテーブルの先頭
  1366. ;                C1(f)/2テーブルのベース
  1367. ;                C2(f)/2テーブルのベース
  1368. ;                Filterルーチン
  1369. ;    Rangeテーブルの先頭
  1370. ;        Range=0~12    [even_range_table_ptr]+2*256*Range
  1371. ;        Range=13~15    無効(データが未対応または壊れているとき参照される可能性がある)
  1372. ;    C1(f)/2テーブルのベース
  1373. ;        Filter=0    無効(絶対に使用されない)
  1374. ;        Filter=1    [c1_1_table_base_ptr]
  1375. ;        Filter=2    [c1_2_table_base_ptr]
  1376. ;        Filter=3    [c1_3_table_base_ptr]
  1377. ;        Filter=4~15    無効(データが未対応または壊れているとき参照される可能性がある)
  1378. ;    C2(f)/2テーブルのベース
  1379. ;        Filter=0    無効(絶対に使用されない)
  1380. ;        Filter=1    無効(絶対に使用されない)
  1381. ;        Filter=2    [c2_2_table_base_ptr]
  1382. ;        Filter=3    [c2_3_table_base_ptr]
  1383. ;        Filter=4~15    無効(データが未対応または壊れているとき参照される可能性がある)
  1384. ;    Filterルーチン
  1385. ;        Filter=0    cdxa_mono_filter_0
  1386. ;        Filter=1    cdxa_mono_filter_1
  1387. ;        Filter=2    cdxa_mono_filter_2
  1388. ;        Filter=3    cdxa_mono_filter_3
  1389. ;        Filter=4~15    無効(データが未対応または壊れているとき参照される可能性がある)
  1390. ;<a0.l:バッファの先頭アドレス(align4)
  1391. ;    16*256=4096bytes
  1392.     move.l    a0,mono_even_filter_table_ptr
  1393.     movea.l    even_range_table_ptr,a1
  1394.     moveq.l    #4-1,d4
  1395. 4:
  1396. ;Filter=0
  1397.     movea.l    a1,a2
  1398.     movea.l    c1_1_table_base_ptr,a3
  1399.     movea.l    c2_2_table_base_ptr,a4
  1400.     lea.l    cdxa_mono_filter_0,a5
  1401.   .irp r,0,1,2,3,4,5,6,7,8,9,10,11
  1402.     movem.l    a2-a5,(16*r,a0)
  1403.     lea.l    (2*256,a2),a2
  1404.   .endm
  1405.   .irp r,12,13,14,15
  1406.     movem.l    a2-a5,(16*r,a0)
  1407.   .endm
  1408.     lea.l    (16*16,a0),a0
  1409. ;Filter=1
  1410.     movea.l    a1,a2
  1411. ;    movea.l    c1_1_table_base_ptr,a3
  1412. ;    movea.l    c2_2_table_base_ptr,a4
  1413.     lea.l    cdxa_mono_filter_1,a5
  1414.   .irp r,0,1,2,3,4,5,6,7,8,9,10,11
  1415.     movem.l    a2-a5,(16*r,a0)
  1416.     lea.l    (2*256,a2),a2
  1417.   .endm
  1418.   .irp r,12,13,14,15
  1419.     movem.l    a2-a5,(16*r,a0)
  1420.   .endm
  1421.     lea.l    (16*16,a0),a0
  1422. ;Filter=2
  1423.     movea.l    a1,a2
  1424.     movea.l    c1_2_table_base_ptr,a3
  1425. ;    movea.l    c2_2_table_base_ptr,a4
  1426.     lea.l    cdxa_mono_filter_2,a5
  1427.   .irp r,0,1,2,3,4,5,6,7,8,9,10,11
  1428.     movem.l    a2-a5,(16*r,a0)
  1429.     lea.l    (2*256,a2),a2
  1430.   .endm
  1431.   .irp r,12,13,14,15
  1432.     movem.l    a2-a5,(16*r,a0)
  1433.   .endm
  1434.     lea.l    (16*16,a0),a0
  1435. ;Filter=3
  1436.     movea.l    a1,a2
  1437.     movea.l    c1_3_table_base_ptr,a3
  1438.     movea.l    c2_3_table_base_ptr,a4
  1439.     lea.l    cdxa_mono_filter_3,a5
  1440.   .irp r,0,1,2,3,4,5,6,7,8,9,10,11
  1441.     movem.l    a2-a5,(16*r,a0)
  1442.     lea.l    (2*256,a2),a2
  1443.   .endm
  1444.   .irp r,12,13,14,15
  1445.     movem.l    a2-a5,(16*r,a0)
  1446.   .endm
  1447.     lea.l    (16*16,a0),a0
  1448.     dbra    d4,4b
  1449. ;----------------------------------------------------------------
  1450. ;モノラル奇数Unit用Filterテーブルを作る
  1451. ;    データの順序は
  1452. ;        Filter(0~3,4~15は無効)
  1453. ;            Range(0~12,13~15は無効)
  1454. ;                Rangeテーブルの先頭
  1455. ;                C1(f)/2テーブルのベース
  1456. ;                C2(f)/2テーブルのベース
  1457. ;                Filterルーチン
  1458. ;    Rangeテーブルの先頭
  1459. ;        Range=0~12    [odd_range_table_ptr]+2*256*Range
  1460. ;        Range=13~15    無効(データが未対応または壊れているとき参照される可能性がある)
  1461. ;    C1(f)/2テーブルのベース
  1462. ;        Filter=0    無効(絶対に使用されない)
  1463. ;        Filter=1    [c1_1_table_base_ptr]
  1464. ;        Filter=2    [c1_2_table_base_ptr]
  1465. ;        Filter=3    [c1_3_table_base_ptr]
  1466. ;        Filter=4~15    無効(データが未対応または壊れているとき参照される可能性がある)
  1467. ;    C2(f)/2テーブルのベース
  1468. ;        Filter=0    無効(絶対に使用されない)
  1469. ;        Filter=1    無効(絶対に使用されない)
  1470. ;        Filter=2    [c2_2_table_base_ptr]
  1471. ;        Filter=3    [c2_3_table_base_ptr]
  1472. ;        Filter=4~15    無効(データが未対応または壊れているとき参照される可能性がある)
  1473. ;    Filterルーチン
  1474. ;        Filter=0    cdxa_mono_filter_0
  1475. ;        Filter=1    cdxa_mono_filter_1
  1476. ;        Filter=2    cdxa_mono_filter_2
  1477. ;        Filter=3    cdxa_mono_filter_3
  1478. ;        Filter=4~15    無効(データが未対応または壊れているとき参照される可能性がある)
  1479. ;<a0.l:バッファの先頭アドレス(align4)
  1480. ;    16*256=4096bytes
  1481.     move.l    a0,mono_odd_filter_table_ptr
  1482.     movea.l    odd_range_table_ptr,a1
  1483.     moveq.l    #4-1,d4
  1484. 4:
  1485. ;Filter=0
  1486.     movea.l    a1,a2
  1487.     movea.l    c1_1_table_base_ptr,a3
  1488.     movea.l    c2_2_table_base_ptr,a4
  1489.     lea.l    cdxa_mono_filter_0,a5
  1490.   .irp r,0,1,2,3,4,5,6,7,8,9,10,11
  1491.     movem.l    a2-a5,(16*r,a0)
  1492.     lea.l    (2*256,a2),a2
  1493.   .endm
  1494.   .irp r,12,13,14,15
  1495.     movem.l    a2-a5,(16*r,a0)
  1496.   .endm
  1497.     lea.l    (16*16,a0),a0
  1498. ;Filter=1
  1499.     movea.l    a1,a2
  1500. ;    movea.l    c1_1_table_base_ptr,a3
  1501. ;    movea.l    c2_2_table_base_ptr,a4
  1502.     lea.l    cdxa_mono_filter_1,a5
  1503.   .irp r,0,1,2,3,4,5,6,7,8,9,10,11
  1504.     movem.l    a2-a5,(16*r,a0)
  1505.     lea.l    (2*256,a2),a2
  1506.   .endm
  1507.   .irp r,12,13,14,15
  1508.     movem.l    a2-a5,(16*r,a0)
  1509.   .endm
  1510.     lea.l    (16*16,a0),a0
  1511. ;Filter=2
  1512.     movea.l    a1,a2
  1513.     movea.l    c1_2_table_base_ptr,a3
  1514. ;    movea.l    c2_2_table_base_ptr,a4
  1515.     lea.l    cdxa_mono_filter_2,a5
  1516.   .irp r,0,1,2,3,4,5,6,7,8,9,10,11
  1517.     movem.l    a2-a5,(16*r,a0)
  1518.     lea.l    (2*256,a2),a2
  1519.   .endm
  1520.   .irp r,12,13,14,15
  1521.     movem.l    a2-a5,(16*r,a0)
  1522.   .endm
  1523.     lea.l    (16*16,a0),a0
  1524. ;Filter=3
  1525.     movea.l    a1,a2
  1526.     movea.l    c1_3_table_base_ptr,a3
  1527.     movea.l    c2_3_table_base_ptr,a4
  1528.     lea.l    cdxa_mono_filter_3,a5
  1529.   .irp r,0,1,2,3,4,5,6,7,8,9,10,11
  1530.     movem.l    a2-a5,(16*r,a0)
  1531.     lea.l    (2*256,a2),a2
  1532.   .endm
  1533.   .irp r,12,13,14,15
  1534.     movem.l    a2-a5,(16*r,a0)
  1535.   .endm
  1536.     lea.l    (16*16,a0),a0
  1537.     dbra    d4,4b
  1538. ;----------------------------------------------------------------
  1539. ;ステレオ偶数Unit(left)用Filterテーブルを作る
  1540. ;    データの順序は
  1541. ;        Filter(0~3,4~15は無効)
  1542. ;            Range(0~12,13~15は無効)
  1543. ;                Rangeテーブルの先頭
  1544. ;                C1(f)/2テーブルのベース
  1545. ;                C2(f)/2テーブルのベース
  1546. ;                Filterルーチン
  1547. ;    Rangeテーブルの先頭
  1548. ;        Range=0~12    [even_range_table_ptr]+2*256*Range
  1549. ;        Range=13~15    無効(データが未対応または壊れているとき参照される可能性がある)
  1550. ;    C1(f)/2テーブルのベース
  1551. ;        Filter=0    無効(絶対に使用されない)
  1552. ;        Filter=1    [c1_1_table_base_ptr]
  1553. ;        Filter=2    [c1_2_table_base_ptr]
  1554. ;        Filter=3    [c1_3_table_base_ptr]
  1555. ;        Filter=4~15    無効(データが未対応または壊れているとき参照される可能性がある)
  1556. ;    C2(f)/2テーブルのベース
  1557. ;        Filter=0    無効(絶対に使用されない)
  1558. ;        Filter=1    無効(絶対に使用されない)
  1559. ;        Filter=2    [c2_2_table_base_ptr]
  1560. ;        Filter=3    [c2_3_table_base_ptr]
  1561. ;        Filter=4~15    無効(データが未対応または壊れているとき参照される可能性がある)
  1562. ;    Filterルーチン
  1563. ;        Filter=0    cdxa_stereo_filter_0
  1564. ;        Filter=1    cdxa_stereo_filter_1
  1565. ;        Filter=2    cdxa_stereo_filter_2
  1566. ;        Filter=3    cdxa_stereo_filter_3
  1567. ;        Filter=4~15    無効(データが未対応または壊れているとき参照される可能性がある)
  1568. ;<a0.l:バッファの先頭アドレス(align4)
  1569. ;    16*256=4096bytes
  1570.     move.l    a0,stereo_even_filter_table_ptr
  1571.     movea.l    even_range_table_ptr,a1
  1572.     moveq.l    #4-1,d4
  1573. 4:
  1574. ;Filter=0
  1575.     movea.l    a1,a2
  1576.     movea.l    c1_1_table_base_ptr,a3
  1577.     movea.l    c2_2_table_base_ptr,a4
  1578.     lea.l    cdxa_stereo_filter_0,a5
  1579.   .irp r,0,1,2,3,4,5,6,7,8,9,10,11
  1580.     movem.l    a2-a5,(16*r,a0)
  1581.     lea.l    (2*256,a2),a2
  1582.   .endm
  1583.   .irp r,12,13,14,15
  1584.     movem.l    a2-a5,(16*r,a0)
  1585.   .endm
  1586.     lea.l    (16*16,a0),a0
  1587. ;Filter=1
  1588.     movea.l    a1,a2
  1589. ;    movea.l    c1_1_table_base_ptr,a3
  1590. ;    movea.l    c2_2_table_base_ptr,a4
  1591.     lea.l    cdxa_stereo_filter_1,a5
  1592.   .irp r,0,1,2,3,4,5,6,7,8,9,10,11
  1593.     movem.l    a2-a5,(16*r,a0)
  1594.     lea.l    (2*256,a2),a2
  1595.   .endm
  1596.   .irp r,12,13,14,15
  1597.     movem.l    a2-a5,(16*r,a0)
  1598.   .endm
  1599.     lea.l    (16*16,a0),a0
  1600. ;Filter=2
  1601.     movea.l    a1,a2
  1602.     movea.l    c1_2_table_base_ptr,a3
  1603. ;    movea.l    c2_2_table_base_ptr,a4
  1604.     lea.l    cdxa_stereo_filter_2,a5
  1605.   .irp r,0,1,2,3,4,5,6,7,8,9,10,11
  1606.     movem.l    a2-a5,(16*r,a0)
  1607.     lea.l    (2*256,a2),a2
  1608.   .endm
  1609.   .irp r,12,13,14,15
  1610.     movem.l    a2-a5,(16*r,a0)
  1611.   .endm
  1612.     lea.l    (16*16,a0),a0
  1613. ;Filter=3
  1614.     movea.l    a1,a2
  1615.     movea.l    c1_3_table_base_ptr,a3
  1616.     movea.l    c2_3_table_base_ptr,a4
  1617.     lea.l    cdxa_stereo_filter_3,a5
  1618.   .irp r,0,1,2,3,4,5,6,7,8,9,10,11
  1619.     movem.l    a2-a5,(16*r,a0)
  1620.     lea.l    (2*256,a2),a2
  1621.   .endm
  1622.   .irp r,12,13,14,15
  1623.     movem.l    a2-a5,(16*r,a0)
  1624.   .endm
  1625.     lea.l    (16*16,a0),a0
  1626.     dbra    d4,4b
  1627. ;----------------------------------------------------------------
  1628. ;ステレオ奇数Unit(right)用Filterテーブルを作る
  1629. ;    データの順序は
  1630. ;        Filter(0~3,4~15は無効)
  1631. ;            Range(0~12,13~15は無効)
  1632. ;                Rangeテーブルの先頭
  1633. ;                C1(f)/2テーブルのベース
  1634. ;                C2(f)/2テーブルのベース
  1635. ;                Filterルーチン
  1636. ;    Rangeテーブルの先頭
  1637. ;        Range=0~12    [odd_range_table_ptr]+2*256*Range
  1638. ;        Range=13~15    無効(データが未対応または壊れているとき参照される可能性がある)
  1639. ;    C1(f)/2テーブルのベース
  1640. ;        Filter=0    無効(絶対に使用されない)
  1641. ;        Filter=1    [c1_1_table_base_ptr]
  1642. ;        Filter=2    [c1_2_table_base_ptr]
  1643. ;        Filter=3    [c1_3_table_base_ptr]
  1644. ;        Filter=4~15    無効(データが未対応または壊れているとき参照される可能性がある)
  1645. ;    C2(f)/2テーブルのベース
  1646. ;        Filter=0    無効(絶対に使用されない)
  1647. ;        Filter=1    無効(絶対に使用されない)
  1648. ;        Filter=2    [c2_2_table_base_ptr]
  1649. ;        Filter=3    [c2_3_table_base_ptr]
  1650. ;        Filter=4~15    無効(データが未対応または壊れているとき参照される可能性がある)
  1651. ;    Filterルーチン
  1652. ;        Filter=0    cdxa_stereo_filter_0
  1653. ;        Filter=1    cdxa_stereo_filter_1
  1654. ;        Filter=2    cdxa_stereo_filter_2
  1655. ;        Filter=3    cdxa_stereo_filter_3
  1656. ;        Filter=4~15    無効(データが未対応または壊れているとき参照される可能性がある)
  1657. ;<a0.l:バッファの先頭アドレス(align4)
  1658. ;    16*256=4096bytes
  1659.     move.l    a0,stereo_odd_filter_table_ptr
  1660.     movea.l    odd_range_table_ptr,a1
  1661.     moveq.l    #4-1,d4
  1662. 4:
  1663. ;Filter=0
  1664.     movea.l    a1,a2
  1665.     movea.l    c1_1_table_base_ptr,a3
  1666.     movea.l    c2_2_table_base_ptr,a4
  1667.     lea.l    cdxa_stereo_filter_0,a5
  1668.   .irp r,0,1,2,3,4,5,6,7,8,9,10,11
  1669.     movem.l    a2-a5,(16*r,a0)
  1670.     lea.l    (2*256,a2),a2
  1671.   .endm
  1672.   .irp r,12,13,14,15
  1673.     movem.l    a2-a5,(16*r,a0)
  1674.   .endm
  1675.     lea.l    (16*16,a0),a0
  1676. ;Filter=1
  1677.     movea.l    a1,a2
  1678. ;    movea.l    c1_1_table_base_ptr,a3
  1679. ;    movea.l    c2_2_table_base_ptr,a4
  1680.     lea.l    cdxa_stereo_filter_1,a5
  1681.   .irp r,0,1,2,3,4,5,6,7,8,9,10,11
  1682.     movem.l    a2-a5,(16*r,a0)
  1683.     lea.l    (2*256,a2),a2
  1684.   .endm
  1685.   .irp r,12,13,14,15
  1686.     movem.l    a2-a5,(16*r,a0)
  1687.   .endm
  1688.     lea.l    (16*16,a0),a0
  1689. ;Filter=2
  1690.     movea.l    a1,a2
  1691.     movea.l    c1_2_table_base_ptr,a3
  1692. ;    movea.l    c2_2_table_base_ptr,a4
  1693.     lea.l    cdxa_stereo_filter_2,a5
  1694.   .irp r,0,1,2,3,4,5,6,7,8,9,10,11
  1695.     movem.l    a2-a5,(16*r,a0)
  1696.     lea.l    (2*256,a2),a2
  1697.   .endm
  1698.   .irp r,12,13,14,15
  1699.     movem.l    a2-a5,(16*r,a0)
  1700.   .endm
  1701.     lea.l    (16*16,a0),a0
  1702. ;Filter=3
  1703.     movea.l    a1,a2
  1704.     movea.l    c1_3_table_base_ptr,a3
  1705.     movea.l    c2_3_table_base_ptr,a4
  1706.     lea.l    cdxa_stereo_filter_3,a5
  1707.   .irp r,0,1,2,3,4,5,6,7,8,9,10,11
  1708.     movem.l    a2-a5,(16*r,a0)
  1709.     lea.l    (2*256,a2),a2
  1710.   .endm
  1711.   .irp r,12,13,14,15
  1712.     movem.l    a2-a5,(16*r,a0)
  1713.   .endm
  1714.     lea.l    (16*16,a0),a0
  1715.     dbra    d4,4b
  1716. ;----------------------------------------------------------------
  1717. ;----------------------------------------------------------------
  1718. ;高精度モノラル偶数Unit用Filterテーブルを作る
  1719. ;    データの順序は
  1720. ;        Filter(0~3,4~15は無効)
  1721. ;            Range(0~12,13~15は無効)
  1722. ;                Rangeテーブルの先頭
  1723. ;                Filterルーチン
  1724. ;    Rangeテーブルの先頭
  1725. ;        Range=0~12    [hq_even_range_table_ptr]+4*256*Range
  1726. ;        Range=13~15    無効(データが未対応または壊れているとき参照される可能性がある)
  1727. ;    Filterルーチン
  1728. ;        Filter=0    cdxa_mono_filter_0_hq
  1729. ;        Filter=1    cdxa_mono_filter_1_hq
  1730. ;        Filter=2    cdxa_mono_filter_2_hq
  1731. ;        Filter=3    cdxa_mono_filter_3_hq
  1732. ;        Filter=4~15    無効(データが未対応または壊れているとき参照される可能性がある)
  1733. ;<a0.l:バッファの先頭アドレス(align4)
  1734. ;    8*256=2048bytes
  1735.     move.l    a0,hq_mono_even_filter_table_ptr
  1736.     movea.l    hq_even_range_table_ptr,a1
  1737.     moveq.l    #4-1,d4
  1738. 4:
  1739. ;Filter=0
  1740.     movea.l    a1,a2
  1741.     lea.l    cdxa_mono_filter_0_hq,a5
  1742.   .irp r,0,1,2,3,4,5,6,7,8,9,10,11
  1743.     movem.l    a2/a5,(8*r,a0)
  1744.     lea.l    (4*256,a2),a2
  1745.   .endm
  1746.   .irp r,12,13,14,15
  1747.     movem.l    a2/a5,(8*r,a0)
  1748.   .endm
  1749.     lea.l    (8*16,a0),a0
  1750. ;Filter=1
  1751.     movea.l    a1,a2
  1752.     lea.l    cdxa_mono_filter_1_hq,a5
  1753.   .irp r,0,1,2,3,4,5,6,7,8,9,10,11
  1754.     movem.l    a2/a5,(8*r,a0)
  1755.     lea.l    (4*256,a2),a2
  1756.   .endm
  1757.   .irp r,12,13,14,15
  1758.     movem.l    a2/a5,(8*r,a0)
  1759.   .endm
  1760.     lea.l    (8*16,a0),a0
  1761. ;Filter=2
  1762.     movea.l    a1,a2
  1763.     lea.l    cdxa_mono_filter_2_hq,a5
  1764.   .irp r,0,1,2,3,4,5,6,7,8,9,10,11
  1765.     movem.l    a2/a5,(8*r,a0)
  1766.     lea.l    (4*256,a2),a2
  1767.   .endm
  1768.   .irp r,12,13,14,15
  1769.     movem.l    a2/a5,(8*r,a0)
  1770.   .endm
  1771.     lea.l    (8*16,a0),a0
  1772. ;Filter=3
  1773.     movea.l    a1,a2
  1774.     lea.l    cdxa_mono_filter_3_hq,a5
  1775.   .irp r,0,1,2,3,4,5,6,7,8,9,10,11
  1776.     movem.l    a2/a5,(8*r,a0)
  1777.     lea.l    (4*256,a2),a2
  1778.   .endm
  1779.   .irp r,12,13,14,15
  1780.     movem.l    a2/a5,(8*r,a0)
  1781.   .endm
  1782.     lea.l    (8*16,a0),a0
  1783.     dbra    d4,4b
  1784. ;----------------------------------------------------------------
  1785. ;高精度モノラル奇数Unit用Filterテーブルを作る
  1786. ;    データの順序は
  1787. ;        Filter(0~3,4~15は無効)
  1788. ;            Range(0~12,13~15は無効)
  1789. ;                Rangeテーブルの先頭
  1790. ;                Filterルーチン
  1791. ;    Rangeテーブルの先頭
  1792. ;        Range=0~12    [hq_odd_range_table_ptr]+4*256*Range
  1793. ;        Range=13~15    無効(データが未対応または壊れているとき参照される可能性がある)
  1794. ;    Filterルーチン
  1795. ;        Filter=0    cdxa_mono_filter_0_hq
  1796. ;        Filter=1    cdxa_mono_filter_1_hq
  1797. ;        Filter=2    cdxa_mono_filter_2_hq
  1798. ;        Filter=3    cdxa_mono_filter_3_hq
  1799. ;        Filter=4~15    無効(データが未対応または壊れているとき参照される可能性がある)
  1800. ;<a0.l:バッファの先頭アドレス(align4)
  1801. ;    8*256=2048bytes
  1802.     move.l    a0,hq_mono_odd_filter_table_ptr
  1803.     movea.l    hq_odd_range_table_ptr,a1
  1804.     moveq.l    #4-1,d4
  1805. 4:
  1806. ;Filter=0
  1807.     movea.l    a1,a2
  1808.     lea.l    cdxa_mono_filter_0_hq,a5
  1809.   .irp r,0,1,2,3,4,5,6,7,8,9,10,11
  1810.     movem.l    a2/a5,(8*r,a0)
  1811.     lea.l    (4*256,a2),a2
  1812.   .endm
  1813.   .irp r,12,13,14,15
  1814.     movem.l    a2/a5,(8*r,a0)
  1815.   .endm
  1816.     lea.l    (8*16,a0),a0
  1817. ;Filter=1
  1818.     movea.l    a1,a2
  1819.     lea.l    cdxa_mono_filter_1_hq,a5
  1820.   .irp r,0,1,2,3,4,5,6,7,8,9,10,11
  1821.     movem.l    a2/a5,(8*r,a0)
  1822.     lea.l    (4*256,a2),a2
  1823.   .endm
  1824.   .irp r,12,13,14,15
  1825.     movem.l    a2/a5,(8*r,a0)
  1826.   .endm
  1827.     lea.l    (8*16,a0),a0
  1828. ;Filter=2
  1829.     movea.l    a1,a2
  1830.     lea.l    cdxa_mono_filter_2_hq,a5
  1831.   .irp r,0,1,2,3,4,5,6,7,8,9,10,11
  1832.     movem.l    a2/a5,(8*r,a0)
  1833.     lea.l    (4*256,a2),a2
  1834.   .endm
  1835.   .irp r,12,13,14,15
  1836.     movem.l    a2/a5,(8*r,a0)
  1837.   .endm
  1838.     lea.l    (8*16,a0),a0
  1839. ;Filter=3
  1840.     movea.l    a1,a2
  1841.     lea.l    cdxa_mono_filter_3_hq,a5
  1842.   .irp r,0,1,2,3,4,5,6,7,8,9,10,11
  1843.     movem.l    a2/a5,(8*r,a0)
  1844.     lea.l    (4*256,a2),a2
  1845.   .endm
  1846.   .irp r,12,13,14,15
  1847.     movem.l    a2/a5,(8*r,a0)
  1848.   .endm
  1849.     lea.l    (8*16,a0),a0
  1850.     dbra    d4,4b
  1851. ;----------------------------------------------------------------
  1852. ;高精度ステレオ偶数Unit(left)用Filterテーブルを作る
  1853. ;    データの順序は
  1854. ;        Filter(0~3,4~15は無効)
  1855. ;            Range(0~12,13~15は無効)
  1856. ;                Rangeテーブルの先頭
  1857. ;                Filterルーチン
  1858. ;    Rangeテーブルの先頭
  1859. ;        Range=0~12    [hq_even_range_table_ptr]+4*256*Range
  1860. ;        Range=13~15    無効(データが未対応または壊れているとき参照される可能性がある)
  1861. ;    Filterルーチン
  1862. ;        Filter=0    cdxa_stereo_filter_0_hq
  1863. ;        Filter=1    cdxa_stereo_filter_1_hq
  1864. ;        Filter=2    cdxa_stereo_filter_2_hq
  1865. ;        Filter=3    cdxa_stereo_filter_3_hq
  1866. ;        Filter=4~15    無効(データが未対応または壊れているとき参照される可能性がある)
  1867. ;<a0.l:バッファの先頭アドレス(align4)
  1868. ;    8*256=2048bytes
  1869.     move.l    a0,hq_stereo_even_filter_table_ptr
  1870.     movea.l    hq_even_range_table_ptr,a1
  1871.     moveq.l    #4-1,d4
  1872. 4:
  1873. ;Filter=0
  1874.     movea.l    a1,a2
  1875.     lea.l    cdxa_stereo_filter_0_hq,a5
  1876.   .irp r,0,1,2,3,4,5,6,7,8,9,10,11
  1877.     movem.l    a2/a5,(8*r,a0)
  1878.     lea.l    (4*256,a2),a2
  1879.   .endm
  1880.   .irp r,12,13,14,15
  1881.     movem.l    a2/a5,(8*r,a0)
  1882.   .endm
  1883.     lea.l    (8*16,a0),a0
  1884. ;Filter=1
  1885.     movea.l    a1,a2
  1886.     lea.l    cdxa_stereo_filter_1_hq,a5
  1887.   .irp r,0,1,2,3,4,5,6,7,8,9,10,11
  1888.     movem.l    a2/a5,(8*r,a0)
  1889.     lea.l    (4*256,a2),a2
  1890.   .endm
  1891.   .irp r,12,13,14,15
  1892.     movem.l    a2/a5,(8*r,a0)
  1893.   .endm
  1894.     lea.l    (8*16,a0),a0
  1895. ;Filter=2
  1896.     movea.l    a1,a2
  1897.     lea.l    cdxa_stereo_filter_2_hq,a5
  1898.   .irp r,0,1,2,3,4,5,6,7,8,9,10,11
  1899.     movem.l    a2/a5,(8*r,a0)
  1900.     lea.l    (4*256,a2),a2
  1901.   .endm
  1902.   .irp r,12,13,14,15
  1903.     movem.l    a2/a5,(8*r,a0)
  1904.   .endm
  1905.     lea.l    (8*16,a0),a0
  1906. ;Filter=3
  1907.     movea.l    a1,a2
  1908.     lea.l    cdxa_stereo_filter_3_hq,a5
  1909.   .irp r,0,1,2,3,4,5,6,7,8,9,10,11
  1910.     movem.l    a2/a5,(8*r,a0)
  1911.     lea.l    (4*256,a2),a2
  1912.   .endm
  1913.   .irp r,12,13,14,15
  1914.     movem.l    a2/a5,(8*r,a0)
  1915.   .endm
  1916.     lea.l    (8*16,a0),a0
  1917.     dbra    d4,4b
  1918. ;----------------------------------------------------------------
  1919. ;高精度ステレオ奇数Unit(right)用Filterテーブルを作る
  1920. ;    データの順序は
  1921. ;        Filter(0~3,4~15は無効)
  1922. ;            Range(0~12,13~15は無効)
  1923. ;                Rangeテーブルの先頭
  1924. ;                Filterルーチン
  1925. ;    Rangeテーブルの先頭
  1926. ;        Range=0~12    [hq_odd_range_table_ptr]+4*256*Range
  1927. ;        Range=13~15    無効(データが未対応または壊れているとき参照される可能性がある)
  1928. ;    Filterルーチン
  1929. ;        Filter=0    cdxa_stereo_filter_0_hq
  1930. ;        Filter=1    cdxa_stereo_filter_1_hq
  1931. ;        Filter=2    cdxa_stereo_filter_2_hq
  1932. ;        Filter=3    cdxa_stereo_filter_3_hq
  1933. ;        Filter=4~15    無効(データが未対応または壊れているとき参照される可能性がある)
  1934. ;<a0.l:バッファの先頭アドレス(align4)
  1935. ;    8*256=2048bytes
  1936.     move.l    a0,hq_stereo_odd_filter_table_ptr
  1937.     movea.l    hq_odd_range_table_ptr,a1
  1938.     moveq.l    #4-1,d4
  1939. 4:
  1940. ;Filter=0
  1941.     movea.l    a1,a2
  1942.     lea.l    cdxa_stereo_filter_0_hq,a5
  1943.   .irp r,0,1,2,3,4,5,6,7,8,9,10,11
  1944.     movem.l    a2/a5,(8*r,a0)
  1945.     lea.l    (4*256,a2),a2
  1946.   .endm
  1947.   .irp r,12,13,14,15
  1948.     movem.l    a2/a5,(8*r,a0)
  1949.   .endm
  1950.     lea.l    (8*16,a0),a0
  1951. ;Filter=1
  1952.     movea.l    a1,a2
  1953.     lea.l    cdxa_stereo_filter_1_hq,a5
  1954.   .irp r,0,1,2,3,4,5,6,7,8,9,10,11
  1955.     movem.l    a2/a5,(8*r,a0)
  1956.     lea.l    (4*256,a2),a2
  1957.   .endm
  1958.   .irp r,12,13,14,15
  1959.     movem.l    a2/a5,(8*r,a0)
  1960.   .endm
  1961.     lea.l    (8*16,a0),a0
  1962. ;Filter=2
  1963.     movea.l    a1,a2
  1964.     lea.l    cdxa_stereo_filter_2_hq,a5
  1965.   .irp r,0,1,2,3,4,5,6,7,8,9,10,11
  1966.     movem.l    a2/a5,(8*r,a0)
  1967.     lea.l    (4*256,a2),a2
  1968.   .endm
  1969.   .irp r,12,13,14,15
  1970.     movem.l    a2/a5,(8*r,a0)
  1971.   .endm
  1972.     lea.l    (8*16,a0),a0
  1973. ;Filter=3
  1974.     movea.l    a1,a2
  1975.     lea.l    cdxa_stereo_filter_3_hq,a5
  1976.   .irp r,0,1,2,3,4,5,6,7,8,9,10,11
  1977.     movem.l    a2/a5,(8*r,a0)
  1978.     lea.l    (4*256,a2),a2
  1979.   .endm
  1980.   .irp r,12,13,14,15
  1981.     movem.l    a2/a5,(8*r,a0)
  1982.   .endm
  1983.     lea.l    (8*16,a0),a0
  1984.     dbra    d4,4b
  1985. ;----------------------------------------------------------------
  1986. 98:    moveq.l    #0,d0
  1987. 99:    movem.l    (sp)+,d1-d7/a0-a6
  1988.     rts
  1989.  
  1990. 90:    moveq.l    #-1,d0
  1991.     bra    99b
  1992.  
  1993. ;----------------------------------------------------------------
  1994. ;----------------------------------------------------------------
  1995. ;CDXA音声セクタデコーダ(モノラル)
  1996. ;<a0.l:PCMバッファの先頭
  1997. ;    2(byte)*28(sample)*8(unit)*18(group)=8064(byte)
  1998. ;<a1.l:CDXAデータセクタの先頭
  1999. ;    Mode2(2336bytes/sector)の先頭(typeの位置)
  2000. ;    +$00    |header||header||fr0123||fr0123|
  2001. ;    +$10    |fr4567||fr4567||    ADPCM
  2002. ;>d0.l:生成されたPCMデータのバイト数(8064)
  2003. ;>a0.l:PCMデータの先頭
  2004. ;>a1.l:CDXAデータセクタの先頭
  2005.     .text
  2006.     .align    4,$2048
  2007. decode_cdxa_mono:
  2008.   .if 1
  2009.     cmpi.b    #LOW_QUALITY,quality_level
  2010.     bne    decode_cdxa_mono_hq
  2011.   .else
  2012.     tst.b    current_mpu_num
  2013.     bne    decode_cdxa_mono_hq
  2014.   .endif
  2015.  
  2016.     movem.l    d1-d7/a0-a6,-(sp)
  2017.     movea.l    a1,a6            ;a6=Sectorの先頭
  2018.  
  2019.     move.w    left1,d0        ;1つ前
  2020.     move.w    left2,d1        ;2つ前
  2021.     addq.l    #8,a6            ;a6=SoundGroupの先頭
  2022.     moveq.l    #18-1,d7        ;g=0~17
  2023. 7:
  2024.   .irp u,0,1,2,3,4,5,6,7
  2025.     moveq.l    #0,d6
  2026.     move.b    (4+u,a6),d6        ;Filter,Range
  2027.     .if (u.and.1)=0
  2028.     movea.l    mono_even_filter_table_ptr,a5
  2029.     .else
  2030.     movea.l    mono_odd_filter_table_ptr,a5
  2031.     .endif
  2032.     lsl.w    #4,d6
  2033.     movem.l    (a5,d6.l),a2-a5        ;a2=Rangeテーブルの先頭
  2034.                     ;a3=C1(f)/2テーブルのベース
  2035.                     ;a4=C2(f)/2テーブルのベース
  2036.                     ;a5=Filterルーチン
  2037.     lea.l    (16+u/2,a6),a1        ;Dataの先頭
  2038.     jsr    (a5)
  2039.   .endm
  2040.     lea.l    (128,a6),a6        ;次のSoundGroupへ
  2041.     dbra    d7,7b
  2042.     move.w    d0,left1        ;1つ前
  2043.     move.w    d1,left2        ;2つ前
  2044.  
  2045.     move.l    a0,d0
  2046.     movem.l    (sp)+,d1-d7/a0-a6
  2047.     sub.l    a0,d0
  2048.     rts
  2049.  
  2050. ;----------------------------------------------------------------
  2051. ;CDXA音声セクタデコーダ(ステレオ左)
  2052. ;<a0.l:PCMバッファの先頭
  2053. ;    2(byte)*28(sample)*4(unit)*18(group)=4032(byte)
  2054. ;<a1.l:CDXAデータセクタの先頭
  2055. ;    Mode2(2336bytes/sector)の先頭(typeの位置)
  2056. ;    +$00    |header||header||fr0123||fr0123|
  2057. ;    +$10    |fr4567||fr4567||    ADPCM
  2058. ;>d0.l:生成されたPCMデータのバイト数(4032)
  2059. ;>a0.l:PCMデータの先頭
  2060. ;>a1.l:CDXAデータセクタの先頭
  2061.     .text
  2062.     .align    4,$2048
  2063. decode_cdxa_stereo_left:
  2064.   .if 1
  2065.     cmpi.b    #LOW_QUALITY,quality_level
  2066.     bne    decode_cdxa_stereo_left_hq
  2067.   .else
  2068.     tst.b    current_mpu_num
  2069.     bne    decode_cdxa_stereo_left_hq
  2070.   .endif
  2071.  
  2072.     movem.l    d1-d7/a0-a6,-(sp)
  2073.     movea.l    a1,a6            ;a6=Sectorの先頭
  2074.  
  2075.     move.w    left1,d0        ;1つ前(left)
  2076.     move.w    left2,d1        ;2つ前(left)
  2077.     addq.l    #8,a6            ;a6=SoundGroupの先頭
  2078.     moveq.l    #18-1,d7        ;g=0~17
  2079. 7:
  2080.   .irp u,0,2,4,6
  2081.     moveq.l    #0,d6
  2082.     move.b    (4+u,a6),d6        ;Filter,Range
  2083.     movea.l    mono_even_filter_table_ptr,a5
  2084.     lsl.w    #4,d6
  2085.     movem.l    (a5,d6.l),a2-a5        ;a2=Rangeテーブルの先頭
  2086.                     ;a3=C1(f)/2テーブルのベース
  2087.                     ;a4=C2(f)/2テーブルのベース
  2088.                     ;a5=Filterルーチン
  2089.     lea.l    (16+u/2,a6),a1        ;Dataの先頭
  2090.     jsr    (a5)
  2091.   .endm
  2092.     lea.l    (128,a6),a6        ;次のSoundGroupへ
  2093.     dbra    d7,7b
  2094.     move.w    d0,left1        ;1つ前(left)
  2095.     move.w    d1,left2        ;2つ前(left)
  2096.  
  2097.     move.l    a0,d0
  2098.     movem.l    (sp)+,d1-d7/a0-a6
  2099.     sub.l    a0,d0
  2100.     rts
  2101.  
  2102. ;----------------------------------------------------------------
  2103. ;CDXA音声セクタデコーダ(ステレオ右)
  2104. ;<a0.l:PCMバッファの先頭
  2105. ;    2(byte)*28(sample)*4(unit)*18(group)=4032(byte)
  2106. ;<a1.l:CDXAデータセクタの先頭
  2107. ;    Mode2(2336bytes/sector)の先頭(typeの位置)
  2108. ;    +$00    |header||header||fr0123||fr0123|
  2109. ;    +$10    |fr4567||fr4567||    ADPCM
  2110. ;>d0.l:生成されたPCMデータのバイト数(4032)
  2111. ;>a0.l:PCMデータの先頭
  2112. ;>a1.l:CDXAデータセクタの先頭
  2113.     .text
  2114.     .align    4,$2048
  2115. decode_cdxa_stereo_right:
  2116.   .if 1
  2117.     cmpi.b    #LOW_QUALITY,quality_level
  2118.     bne    decode_cdxa_stereo_right_hq
  2119.   .else
  2120.     tst.b    current_mpu_num
  2121.     bne    decode_cdxa_stereo_right_hq
  2122.   .endif
  2123.  
  2124.     movem.l    d1-d7/a0-a6,-(sp)
  2125.     movea.l    a1,a6            ;a6=Sectorの先頭
  2126.  
  2127.     move.w    right1,d0        ;1つ前(right)
  2128.     move.w    right2,d1        ;2つ前(right)
  2129.     addq.l    #8,a6            ;a6=SoundGroupの先頭
  2130.     moveq.l    #18-1,d7        ;g=0~17
  2131. 7:
  2132.   .irp u,1,3,5,7
  2133.     moveq.l    #0,d6
  2134.     move.b    (4+u,a6),d6        ;Filter,Range
  2135.     movea.l    mono_odd_filter_table_ptr,a5
  2136.     lsl.w    #4,d6
  2137.     movem.l    (a5,d6.l),a2-a5        ;a2=Rangeテーブルの先頭
  2138.                     ;a3=C1(f)/2テーブルのベース
  2139.                     ;a4=C2(f)/2テーブルのベース
  2140.                     ;a5=Filterルーチン
  2141.     lea.l    (16+u/2,a6),a1        ;Dataの先頭
  2142.     jsr    (a5)
  2143.   .endm
  2144.     lea.l    (128,a6),a6        ;次のSoundGroupへ
  2145.     dbra    d7,7b
  2146.     move.w    d0,right1        ;1つ前(right)
  2147.     move.w    d1,right2        ;2つ前(right)
  2148.  
  2149.     move.l    a0,d0
  2150.     movem.l    (sp)+,d1-d7/a0-a6
  2151.     sub.l    a0,d0
  2152.     rts
  2153.  
  2154. ;----------------------------------------------------------------
  2155. ;CDXA音声セクタデコーダ(ステレオ左右)
  2156. ;<a0.l:PCMバッファの先頭
  2157. ;    2(byte)*28(sample)*8(unit)*18(group)=8064(byte)
  2158. ;<a1.l:CDXAデータセクタの先頭
  2159. ;    Mode2(2336bytes/sector)の先頭(typeの位置)
  2160. ;    +$00    |header||header||fr0123||fr0123|
  2161. ;    +$10    |fr4567||fr4567||    ADPCM
  2162. ;>d0.l:生成されたPCMデータのバイト数(8064)
  2163. ;>a0.l:PCMデータの先頭
  2164. ;>a1.l:CDXAデータセクタの先頭
  2165.     .text
  2166.     .align    4,$2048
  2167. decode_cdxa_stereo_both:
  2168.   .if 1
  2169.     cmpi.b    #LOW_QUALITY,quality_level
  2170.     bne    decode_cdxa_stereo_both_hq
  2171.   .else
  2172.     tst.b    current_mpu_num
  2173.     bne    decode_cdxa_stereo_both_hq
  2174.   .endif
  2175.  
  2176.     movem.l    d1-d7/a0-a6,-(sp)
  2177.     movea.l    a1,a6            ;a6=Sectorの先頭
  2178.  
  2179.     move.w    left1,d0        ;1つ前(left)
  2180.     move.w    left2,d1        ;2つ前(left)
  2181.     move.w    right1,d2        ;1つ前(right)
  2182.     move.w    right2,d3        ;2つ前(right)
  2183.     addq.l    #8,a6            ;a6=SoundGroupの先頭
  2184.     moveq.l    #18-1,d7        ;g=0~17
  2185. 7:
  2186.   .irp u,0,1,2,3,4,5,6,7
  2187.     moveq.l    #0,d6
  2188.     move.b    (4+u,a6),d6        ;Filter,Range
  2189.     .if (u.and.1)=0
  2190.     movea.l    stereo_even_filter_table_ptr,a5
  2191.     .else
  2192.     movea.l    stereo_odd_filter_table_ptr,a5
  2193.     .endif
  2194.     lsl.w    #4,d6
  2195.     movem.l    (a5,d6.l),a2-a5        ;a2=Rangeテーブルの先頭
  2196.                     ;a3=C1(f)/2テーブルのベース
  2197.                     ;a4=C2(f)/2テーブルのベース
  2198.                     ;a5=Filterルーチン
  2199.     lea.l    (16+u/2,a6),a1        ;Dataの先頭
  2200.     jsr    (a5)
  2201.     .if (u.and.1)=0
  2202.     addq.l    #2,a0            ;left→right
  2203.     .else
  2204.     lea.l    (-2+4*28,a0),a0
  2205.     .endif
  2206.     exg.l    d0,d2
  2207.     exg.l    d1,d3
  2208.   .endm
  2209.     lea.l    (128,a6),a6        ;次のSoundGroupへ
  2210.     dbra    d7,7b
  2211.     move.w    d0,left1        ;1つ前(left)
  2212.     move.w    d1,left2        ;2つ前(left)
  2213.     move.w    d2,right1        ;1つ前(right)
  2214.     move.w    d3,right2        ;2つ前(right)
  2215.  
  2216.     move.l    a0,d0
  2217.     movem.l    (sp)+,d1-d7/a0-a6
  2218.     sub.l    a0,d0
  2219.     rts
  2220.  
  2221. ;----------------------------------------------------------------
  2222. ;----------------------------------------------------------------
  2223. ;CDXA音声セクタデコーダ(高精度モノラル)
  2224. ;<a0.l:PCMバッファの先頭
  2225. ;    2(byte)*28(sample)*8(unit)*18(group)=8064(byte)
  2226. ;<a1.l:CDXAデータセクタの先頭
  2227. ;    Mode2(2336bytes/sector)の先頭(typeの位置)
  2228. ;    +$00    |header||header||fr0123||fr0123|
  2229. ;    +$10    |fr4567||fr4567||    ADPCM
  2230. ;>d0.l:生成されたPCMデータのバイト数(8064)
  2231. ;>a0.l:PCMデータの先頭
  2232. ;>a1.l:CDXAデータセクタの先頭
  2233.     .text
  2234.     .align    4,$2048
  2235. decode_cdxa_mono_hq:
  2236.     movem.l    d1-d7/a0-a6,-(sp)
  2237.     movea.l    a1,a6            ;a6=Sectorの先頭
  2238.  
  2239.     move.l    left1,d0        ;1つ前
  2240.     move.l    left2,d1        ;2つ前
  2241.     addq.l    #8,a6            ;a6=SoundGroupの先頭
  2242.     moveq.l    #18-1,d7        ;g=0~17
  2243. 7:
  2244.   .irp u,0,1,2,3,4,5,6,7
  2245.     moveq.l    #0,d6
  2246.     move.b    (4+u,a6),d6        ;Filter,Range
  2247.     .if (u.and.1)=0
  2248.     movea.l    hq_mono_even_filter_table_ptr,a5
  2249.     .else
  2250.     movea.l    hq_mono_odd_filter_table_ptr,a5
  2251.     .endif
  2252.     lsl.w    #3,d6
  2253.     movem.l    (a5,d6.l),a2/a5        ;a2=Rangeテーブルの先頭
  2254.                     ;a5=Filterルーチン
  2255.     lea.l    (16+u/2,a6),a1        ;Dataの先頭
  2256.     jsr    (a5)
  2257.   .endm
  2258.     lea.l    (128,a6),a6        ;次のSoundGroupへ
  2259.     dbra    d7,7b
  2260.     move.l    d0,left1        ;1つ前
  2261.     move.l    d1,left2        ;2つ前
  2262.  
  2263.     move.l    a0,d0
  2264.     movem.l    (sp)+,d1-d7/a0-a6
  2265.     sub.l    a0,d0
  2266.     rts
  2267.  
  2268. ;----------------------------------------------------------------
  2269. ;CDXA音声セクタデコーダ(高精度ステレオ左)
  2270. ;<a0.l:PCMバッファの先頭
  2271. ;    2(byte)*28(sample)*4(unit)*18(group)=4032(byte)
  2272. ;<a1.l:CDXAデータセクタの先頭
  2273. ;    Mode2(2336bytes/sector)の先頭(typeの位置)
  2274. ;    +$00    |header||header||fr0123||fr0123|
  2275. ;    +$10    |fr4567||fr4567||    ADPCM
  2276. ;>d0.l:生成されたPCMデータのバイト数(4032)
  2277. ;>a0.l:PCMデータの先頭
  2278. ;>a1.l:CDXAデータセクタの先頭
  2279.     .text
  2280.     .align    4,$2048
  2281. decode_cdxa_stereo_left_hq:
  2282.     movem.l    d1-d7/a0-a6,-(sp)
  2283.     movea.l    a1,a6            ;a6=Sectorの先頭
  2284.  
  2285.     move.l    left1,d0        ;1つ前(left)
  2286.     move.l    left2,d1        ;2つ前(left)
  2287.     addq.l    #8,a6            ;a6=SoundGroupの先頭
  2288.     moveq.l    #18-1,d7        ;g=0~17
  2289. 7:
  2290.   .irp u,0,2,4,6
  2291.     moveq.l    #0,d6
  2292.     move.b    (4+u,a6),d6        ;Filter,Range
  2293.     movea.l    hq_mono_even_filter_table_ptr,a5
  2294.     lsl.w    #3,d6
  2295.     movem.l    (a5,d6.l),a2/a5        ;a2=Rangeテーブルの先頭
  2296.                     ;a5=Filterルーチン
  2297.     lea.l    (16+u/2,a6),a1        ;Dataの先頭
  2298.     jsr    (a5)
  2299.   .endm
  2300.     lea.l    (128,a6),a6        ;次のSoundGroupへ
  2301.     dbra    d7,7b
  2302.     move.l    d0,left1        ;1つ前(left)
  2303.     move.l    d1,left2        ;2つ前(left)
  2304.  
  2305.     move.l    a0,d0
  2306.     movem.l    (sp)+,d1-d7/a0-a6
  2307.     sub.l    a0,d0
  2308.     rts
  2309.  
  2310. ;----------------------------------------------------------------
  2311. ;CDXA音声セクタデコーダ(高精度ステレオ右)
  2312. ;<a0.l:PCMバッファの先頭
  2313. ;    2(byte)*28(sample)*4(unit)*18(group)=4032(byte)
  2314. ;<a1.l:CDXAデータセクタの先頭
  2315. ;    Mode2(2336bytes/sector)の先頭(typeの位置)
  2316. ;    +$00    |header||header||fr0123||fr0123|
  2317. ;    +$10    |fr4567||fr4567||    ADPCM
  2318. ;>d0.l:生成されたPCMデータのバイト数(4032)
  2319. ;>a0.l:PCMデータの先頭
  2320. ;>a1.l:CDXAデータセクタの先頭
  2321.     .text
  2322.     .align    4,$2048
  2323. decode_cdxa_stereo_right_hq:
  2324.     movem.l    d1-d7/a0-a6,-(sp)
  2325.     movea.l    a1,a6            ;a6=Sectorの先頭
  2326.  
  2327.     move.l    right1,d0        ;1つ前(right)
  2328.     move.l    right2,d1        ;2つ前(right)
  2329.     addq.l    #8,a6            ;a6=SoundGroupの先頭
  2330.     moveq.l    #18-1,d7        ;g=0~17
  2331. 7:
  2332.   .irp u,1,3,5,7
  2333.     moveq.l    #0,d6
  2334.     move.b    (4+u,a6),d6        ;Filter,Range
  2335.     movea.l    hq_mono_odd_filter_table_ptr,a5
  2336.     lsl.w    #3,d6
  2337.     movem.l    (a5,d6.l),a2/a5        ;a2=Rangeテーブルの先頭
  2338.                     ;a3=C1(f)/2テーブルのベース
  2339.                     ;a4=C2(f)/2テーブルのベース
  2340.                     ;a5=Filterルーチン
  2341.     lea.l    (16+u/2,a6),a1        ;Dataの先頭
  2342.     jsr    (a5)
  2343.   .endm
  2344.     lea.l    (128,a6),a6        ;次のSoundGroupへ
  2345.     dbra    d7,7b
  2346.     move.l    d0,right1        ;1つ前(right)
  2347.     move.l    d1,right2        ;2つ前(right)
  2348.  
  2349.     move.l    a0,d0
  2350.     movem.l    (sp)+,d1-d7/a0-a6
  2351.     sub.l    a0,d0
  2352.     rts
  2353.  
  2354. ;----------------------------------------------------------------
  2355. ;CDXA音声セクタデコーダ(高精度ステレオ左右)
  2356. ;<a0.l:PCMバッファの先頭
  2357. ;    2(byte)*28(sample)*8(unit)*18(group)=8064(byte)
  2358. ;<a1.l:CDXAデータセクタの先頭
  2359. ;    Mode2(2336bytes/sector)の先頭(typeの位置)
  2360. ;    +$00    |header||header||fr0123||fr0123|
  2361. ;    +$10    |fr4567||fr4567||    ADPCM
  2362. ;>d0.l:生成されたPCMデータのバイト数(8064)
  2363. ;>a0.l:PCMデータの先頭
  2364. ;>a1.l:CDXAデータセクタの先頭
  2365.     .text
  2366.     .align    4,$2048
  2367. decode_cdxa_stereo_both_hq:
  2368.     movem.l    d1-d7/a0-a6,-(sp)
  2369.     movea.l    a1,a6            ;a6=Sectorの先頭
  2370.  
  2371.     move.l    left1,d0        ;1つ前(left)
  2372.     move.l    left2,d1        ;2つ前(left)
  2373.     move.l    right1,d2        ;1つ前(right)
  2374.     move.l    right2,d3        ;2つ前(right)
  2375.     addq.l    #8,a6            ;a6=SoundGroupの先頭
  2376.     moveq.l    #18-1,d7        ;g=0~17
  2377. 7:
  2378.   .irp u,0,1,2,3,4,5,6,7
  2379.     moveq.l    #0,d6
  2380.     move.b    (4+u,a6),d6        ;Filter,Range
  2381.     .if (u.and.1)=0
  2382.     movea.l    hq_stereo_even_filter_table_ptr,a5
  2383.     .else
  2384.     movea.l    hq_stereo_odd_filter_table_ptr,a5
  2385.     .endif
  2386.     lsl.w    #3,d6
  2387.     movem.l    (a5,d6.l),a2/a5        ;a2=Rangeテーブルの先頭
  2388.                     ;a5=Filterルーチン
  2389.     lea.l    (16+u/2,a6),a1        ;Dataの先頭
  2390.     jsr    (a5)
  2391.     .if (u.and.1)=0
  2392.     addq.l    #2,a0            ;left→right
  2393.     .else
  2394.     lea.l    (-2+4*28,a0),a0
  2395.     .endif
  2396.     exg.l    d0,d2
  2397.     exg.l    d1,d3
  2398.   .endm
  2399.     lea.l    (128,a6),a6        ;次のSoundGroupへ
  2400.     dbra    d7,7b
  2401.     move.l    d0,left1        ;1つ前(left)
  2402.     move.l    d1,left2        ;2つ前(left)
  2403.     move.l    d2,right1        ;1つ前(right)
  2404.     move.l    d3,right2        ;2つ前(right)
  2405.  
  2406.     move.l    a0,d0
  2407.     movem.l    (sp)+,d1-d7/a0-a6
  2408.     sub.l    a0,d0
  2409.     rts
  2410.  
  2411. ;----------------------------------------------------------------
  2412. ;----------------------------------------------------------------
  2413. ;モノラルFilter=0
  2414. ;<d0.w:1つ前のPCMデータ
  2415. ;<d1.w:2つ前のPCMデータ
  2416. ;<a0.l:PCMバッファの位置
  2417. ;<a1.l:Sample(0)のDataの位置
  2418. ;<a2.l:現在のRangeテーブル(11~-1)
  2419. ;    偶数Unitならば下位4bitのみ,奇数Unitならば上位4bitのみを使用し,
  2420. ;    残りのビットを無視するような構造のテーブル
  2421. ;    2*256*13=6656バイト
  2422. ;>d0.w:1つ前のPCMデータ
  2423. ;>d1.w:2つ前のPCMデータ
  2424. ;>a0.l:(+2*28)
  2425.     .text
  2426.     .align    4,$2048
  2427. cdxa_mono_filter_0:
  2428. s = 0
  2429.   .rept 14
  2430.     moveq.l    #0,d1
  2431.     move.b    (4*s,a1),d1        ;Data=$?dまたは$d?
  2432.     add.w    d1,d1
  2433.     move.w    (a2,d1.w),d1        ;d<<(11-Range(u))
  2434.     add.w    d1,d1
  2435.     move.w    d1,(a0)+
  2436. s = s+1
  2437.     moveq.l    #0,d0
  2438.     move.b    (4*s,a1),d0        ;Data=$?dまたは$d?
  2439.     add.w    d0,d0
  2440.     move.w    (a2,d0.w),d0        ;d<<(11-Range(u))
  2441.     add.w    d0,d0
  2442.     move.w    d0,(a0)+
  2443. s = s+1
  2444.   .endm
  2445.     .fail    s<>28
  2446.     rts
  2447.  
  2448. ;----------------------------------------------------------------
  2449. ;モノラルFilter=1
  2450. ;<d0.w:1つ前のPCMデータ
  2451. ;<d1.w:2つ前のPCMデータ
  2452. ;<a0.l:PCMバッファの位置
  2453. ;<a1.l:Sample(0)のDataの位置
  2454. ;<a2.l:現在のRangeテーブル(11~-1)
  2455. ;    偶数Unitならば下位4bitのみ,奇数Unitならば上位4bitのみを使用し,
  2456. ;    残りのビットを無視するような構造のテーブル
  2457. ;    2*256*13=6656バイト
  2458. ;<a3.l:C1(1)/2テーブルのベース
  2459. ;    ベースはオフセットが0の位置であり,テーブルはベースを挟んで前後に展開される
  2460. ;>d0.w:1つ前のPCMデータ
  2461. ;>d1.w:2つ前のPCMデータ
  2462. ;>a0.l:(+2*28)
  2463.     .text
  2464.     .align    4,$2048
  2465. cdxa_mono_filter_1:
  2466. s = 0
  2467.   .rept 14
  2468.     moveq.l    #0,d1
  2469.     move.b    (4*s,a1),d1        ;Data=$?dまたは$d?
  2470.     add.w    d1,d1
  2471.     move.w    (a2,d1.w),d1        ;d<<(11-Range(u))
  2472.     add.w    (a3,d0.w),d1        ;p1*C1(1)
  2473.     add.w    d1,d1
  2474.     move.w    d1,(a0)+
  2475. s = s+1
  2476.     moveq.l    #0,d0
  2477.     move.b    (4*s,a1),d0        ;Data=$?dまたは$d?
  2478.     add.w    d0,d0
  2479.     move.w    (a2,d0.w),d0        ;d<<(11-Range(u))
  2480.     add.w    (a3,d1.w),d0        ;p1*C1(1)
  2481.     add.w    d0,d0
  2482.     move.w    d0,(a0)+
  2483. s = s+1
  2484.   .endm
  2485.     .fail    s<>28
  2486.     rts
  2487.  
  2488. ;----------------------------------------------------------------
  2489. ;モノラルFilter=2
  2490. ;<d0.w:1つ前のPCMデータ
  2491. ;<d1.w:2つ前のPCMデータ
  2492. ;<a0.l:PCMバッファの位置
  2493. ;<a1.l:Sample(0)のDataの位置
  2494. ;<a2.l:現在のRangeテーブル(11~-1)
  2495. ;    偶数Unitならば下位4bitのみ,奇数Unitならば上位4bitのみを使用し,
  2496. ;    残りのビットを無視するような構造のテーブル
  2497. ;    2*256*13=6656バイト
  2498. ;<a3.l:C1(2)/2テーブルのベース
  2499. ;    ベースはオフセットが0の位置であり,テーブルはベースを挟んで前後に展開される
  2500. ;<a4.l:C2(2)/2テーブルのベース
  2501. ;    ベースはオフセットが0の位置であり,テーブルはベースを挟んで前後に展開される
  2502. ;>d0.w:1つ前のPCMデータ
  2503. ;>d1.w:2つ前のPCMデータ
  2504. ;>a0.l:(+2*28)
  2505. ;?d4
  2506.     .text
  2507.     .align    4,$2048
  2508. cdxa_mono_filter_2:
  2509. s = 0
  2510.   .rept 9
  2511.     moveq.l    #0,d4
  2512.     move.b    (4*s,a1),d4        ;Data=$?dまたは$d?
  2513.     add.w    d4,d4
  2514.     move.w    (a2,d4.w),d4        ;d<<(11-Range(u))
  2515.     add.w    (a3,d0.w),d4        ;p1*C1(2)
  2516.     add.w    (a4,d1.w),d4        ;p2*C2(2)
  2517.     add.w    d4,d4
  2518.     move.w    d4,(a0)+
  2519. s = s+1
  2520.     moveq.l    #0,d1
  2521.     move.b    (4*s,a1),d1        ;Data=$?dまたは$d?
  2522.     add.w    d1,d1
  2523.     move.w    (a2,d1.w),d1        ;d<<(11-Range(u))
  2524.     add.w    (a3,d4.w),d1        ;p1*C1(2)
  2525.     add.w    (a4,d0.w),d1        ;p2*C2(2)
  2526.     add.w    d1,d1
  2527.     move.w    d1,(a0)+
  2528. s = s+1
  2529.     moveq.l    #0,d0
  2530.     move.b    (4*s,a1),d0        ;Data=$?dまたは$d?
  2531.     add.w    d0,d0
  2532.     move.w    (a2,d0.w),d0        ;d<<(11-Range(u))
  2533.     add.w    (a3,d1.w),d0        ;p1*C1(2)
  2534.     add.w    (a4,d4.w),d0        ;p2*C2(2)
  2535.     add.w    d0,d0
  2536.     move.w    d0,(a0)+
  2537. s = s+1
  2538.   .endm
  2539.     moveq.l    #0,d4
  2540.     move.b    (4*s,a1),d4        ;Data=$?dまたは$d?
  2541.     add.w    d4,d4
  2542.     move.w    (a2,d4.w),d4        ;d<<(11-Range(u))
  2543.     add.w    (a3,d0.w),d4        ;p1*C1(2)
  2544.     add.w    (a4,d1.w),d4        ;p2*C2(2)
  2545.     add.w    d4,d4
  2546.     move.w    d4,(a0)+
  2547. s = s+1
  2548.     move.w    d0,d1
  2549.     move.w    d4,d0
  2550.     .fail    s<>28
  2551.     rts
  2552.  
  2553. ;----------------------------------------------------------------
  2554. ;モノラルFilter=3
  2555. ;<d0.w:1つ前のPCMデータ
  2556. ;<d1.w:2つ前のPCMデータ
  2557. ;<a0.l:PCMバッファの位置
  2558. ;<a1.l:Sample(0)のDataの位置
  2559. ;<a2.l:現在のRangeテーブル(11~-1)
  2560. ;    偶数Unitならば下位4bitのみ,奇数Unitならば上位4bitのみを使用し,
  2561. ;    残りのビットを無視するような構造のテーブル
  2562. ;    2*256*13=6656バイト
  2563. ;<a3.l:C1(3)/2テーブルのベース
  2564. ;    ベースはオフセットが0の位置であり,テーブルはベースを挟んで前後に展開される
  2565. ;<a4.l:C2(3)/2テーブルのベース
  2566. ;    ベースはオフセットが0の位置であり,テーブルはベースを挟んで前後に展開される
  2567. ;>d0.w:1つ前のPCMデータ
  2568. ;>d1.w:2つ前のPCMデータ
  2569. ;>a0.l:(+2*28)
  2570. ;?d4
  2571.   .if 1
  2572. ;cdxa_mono_filter_3はcdxa_mono_filter_2とまったく同じなので省略
  2573. cdxa_mono_filter_3    equ    cdxa_mono_filter_2
  2574.   .else
  2575.     .text
  2576.     .align    4,$2048
  2577. cdxa_mono_filter_3:
  2578. s = 0
  2579.   .rept 9
  2580.     moveq.l    #0,d4
  2581.     move.b    (4*s,a1),d4        ;Data=$?dまたは$d?
  2582.     add.w    d4,d4
  2583.     move.w    (a2,d4.w),d4        ;d<<(11-Range(u))
  2584.     add.w    (a3,d0.w),d4        ;p1*C1(3)
  2585.     add.w    (a4,d1.w),d4        ;p2*C2(3)
  2586.     add.w    d4,d4
  2587.     move.w    d4,(a0)+
  2588. s = s+1
  2589.     moveq.l    #0,d1
  2590.     move.b    (4*s,a1),d1        ;Data=$?dまたは$d?
  2591.     add.w    d1,d1
  2592.     move.w    (a2,d1.w),d1        ;d<<(11-Range(u))
  2593.     add.w    (a3,d4.w),d1        ;p1*C1(3)
  2594.     add.w    (a4,d0.w),d1        ;p2*C2(3)
  2595.     add.w    d1,d1
  2596.     move.w    d1,(a0)+
  2597. s = s+1
  2598.     moveq.l    #0,d0
  2599.     move.b    (4*s,a1),d0        ;Data=$?dまたは$d?
  2600.     add.w    d0,d0
  2601.     move.w    (a2,d0.w),d0        ;d<<(11-Range(u))
  2602.     add.w    (a3,d1.w),d0        ;p1*C1(3)
  2603.     add.w    (a4,d4.w),d0        ;p2*C2(3)
  2604.     add.w    d0,d0
  2605.     move.w    d0,(a0)+
  2606. s = s+1
  2607.   .endm
  2608.     moveq.l    #0,d4
  2609.     move.b    (4*s,a1),d4        ;Data=$?dまたは$d?
  2610.     add.w    d4,d4
  2611.     move.w    (a2,d4.w),d4        ;d<<(11-Range(u))
  2612.     add.w    (a3,d0.w),d4        ;p1*C1(3)
  2613.     add.w    (a4,d1.w),d4        ;p2*C2(3)
  2614.     add.w    d4,d4
  2615.     move.w    d4,(a0)+
  2616. s = s+1
  2617.     move.w    d0,d1
  2618.     move.w    d4,d0
  2619.     .fail    s<>28
  2620.     rts
  2621.   .endif
  2622.  
  2623. ;----------------------------------------------------------------
  2624. ;----------------------------------------------------------------
  2625. ;ステレオFilter=0
  2626. ;<d0.w:1つ前のPCMデータ
  2627. ;<d1.w:2つ前のPCMデータ
  2628. ;<a0.l:PCMバッファの位置
  2629. ;<a1.l:Sample(0)のDataの位置
  2630. ;<a2.l:現在のRangeテーブル(11~-1)
  2631. ;    偶数Unitならば下位4bitのみ,奇数Unitならば上位4bitのみを使用し,
  2632. ;    残りのビットを無視するような構造のテーブル
  2633. ;    2*256*13=6656バイト
  2634. ;>d0.w:1つ前のPCMデータ
  2635. ;>d1.w:2つ前のPCMデータ
  2636. ;>a0.l:(変化しない)
  2637.     .text
  2638.     .align    4,$2048
  2639. cdxa_stereo_filter_0:
  2640. s = 0
  2641.   .rept 14
  2642.     moveq.l    #0,d1
  2643.     move.b    (4*s,a1),d1        ;Data=$?dまたは$d?
  2644.     add.w    d1,d1
  2645.     move.w    (a2,d1.w),d1        ;d<<(11-Range(u))
  2646.     add.w    d1,d1
  2647.     move.w    d1,(4*s,a0)
  2648. s = s+1
  2649.     moveq.l    #0,d0
  2650.     move.b    (4*s,a1),d0        ;Data=$?dまたは$d?
  2651.     add.w    d0,d0
  2652.     move.w    (a2,d0.w),d0        ;d<<(11-Range(u))
  2653.     add.w    d0,d0
  2654.     move.w    d0,(4*s,a0)
  2655. s = s+1
  2656.   .endm
  2657.     .fail    s<>28
  2658.     rts
  2659.  
  2660. ;----------------------------------------------------------------
  2661. ;ステレオFilter=1
  2662. ;<d0.w:1つ前のPCMデータ
  2663. ;<d1.w:2つ前のPCMデータ
  2664. ;<a0.l:PCMバッファの位置
  2665. ;<a1.l:Sample(0)のDataの位置
  2666. ;<a2.l:現在のRangeテーブル(11~-1)
  2667. ;    偶数Unitならば下位4bitのみ,奇数Unitならば上位4bitのみを使用し,
  2668. ;    残りのビットを無視するような構造のテーブル
  2669. ;    2*256*13=6656バイト
  2670. ;<a3.l:C1(1)/2テーブルのベース
  2671. ;    ベースはオフセットが0の位置であり,テーブルはベースを挟んで前後に展開される
  2672. ;>d0.w:1つ前のPCMデータ
  2673. ;>d1.w:2つ前のPCMデータ
  2674. ;>a0.l:(変化しない)
  2675.     .text
  2676.     .align    4,$2048
  2677. cdxa_stereo_filter_1:
  2678. s = 0
  2679.   .rept 14
  2680.     moveq.l    #0,d1
  2681.     move.b    (4*s,a1),d1        ;Data=$?dまたは$d?
  2682.     add.w    d1,d1
  2683.     move.w    (a2,d1.w),d1        ;d<<(11-Range(u))
  2684.     add.w    (a3,d0.w),d1        ;p1*C1(1)
  2685.     add.w    d1,d1
  2686.     move.w    d1,(4*s,a0)
  2687. s = s+1
  2688.     moveq.l    #0,d0
  2689.     move.b    (4*s,a1),d0        ;Data=$?dまたは$d?
  2690.     add.w    d0,d0
  2691.     move.w    (a2,d0.w),d0        ;d<<(11-Range(u))
  2692.     add.w    (a3,d1.w),d0        ;p1*C1(1)
  2693.     add.w    d0,d0
  2694.     move.w    d0,(4*s,a0)
  2695. s = s+1
  2696.   .endm
  2697.     .fail    s<>28
  2698.     rts
  2699.  
  2700. ;----------------------------------------------------------------
  2701. ;ステレオFilter=2
  2702. ;<d0.w:1つ前のPCMデータ
  2703. ;<d1.w:2つ前のPCMデータ
  2704. ;<a0.l:PCMバッファの位置
  2705. ;<a1.l:Sample(0)のDataの位置
  2706. ;<a2.l:現在のRangeテーブル(11~-1)
  2707. ;    偶数Unitならば下位4bitのみ,奇数Unitならば上位4bitのみを使用し,
  2708. ;    残りのビットを無視するような構造のテーブル
  2709. ;    2*256*13=6656バイト
  2710. ;<a3.l:C1(2)/2テーブルのベース
  2711. ;    ベースはオフセットが0の位置であり,テーブルはベースを挟んで前後に展開される
  2712. ;<a4.l:C2(2)/2テーブルのベース
  2713. ;    ベースはオフセットが0の位置であり,テーブルはベースを挟んで前後に展開される
  2714. ;>d0.w:1つ前のPCMデータ
  2715. ;>d1.w:2つ前のPCMデータ
  2716. ;>a0.l:(変化しない)
  2717. ;?d4
  2718.     .text
  2719.     .align    4,$2048
  2720. cdxa_stereo_filter_2:
  2721. s = 0
  2722.   .rept 9
  2723.     moveq.l    #0,d4
  2724.     move.b    (4*s,a1),d4        ;Data=$?dまたは$d?
  2725.     add.w    d4,d4
  2726.     move.w    (a2,d4.w),d4        ;d<<(11-Range(u))
  2727.     add.w    (a3,d0.w),d4        ;p1*C1(2)
  2728.     add.w    (a4,d1.w),d4        ;p2*C2(2)
  2729.     add.w    d4,d4
  2730.     move.w    d4,(4*s,a0)
  2731. s = s+1
  2732.     moveq.l    #0,d1
  2733.     move.b    (4*s,a1),d1        ;Data=$?dまたは$d?
  2734.     add.w    d1,d1
  2735.     move.w    (a2,d1.w),d1        ;d<<(11-Range(u))
  2736.     add.w    (a3,d4.w),d1        ;p1*C1(2)
  2737.     add.w    (a4,d0.w),d1        ;p2*C2(2)
  2738.     add.w    d1,d1
  2739.     move.w    d1,(4*s,a0)
  2740. s = s+1
  2741.     moveq.l    #0,d0
  2742.     move.b    (4*s,a1),d0        ;Data=$?dまたは$d?
  2743.     add.w    d0,d0
  2744.     move.w    (a2,d0.w),d0        ;d<<(11-Range(u))
  2745.     add.w    (a3,d1.w),d0        ;p1*C1(2)
  2746.     add.w    (a4,d4.w),d0        ;p2*C2(2)
  2747.     add.w    d0,d0
  2748.     move.w    d0,(4*s,a0)
  2749. s = s+1
  2750.   .endm
  2751.     moveq.l    #0,d4
  2752.     move.b    (4*s,a1),d4        ;Data=$?dまたは$d?
  2753.     add.w    d4,d4
  2754.     move.w    (a2,d4.w),d4        ;d<<(11-Range(u))
  2755.     add.w    (a3,d0.w),d4        ;p1*C1(2)
  2756.     add.w    (a4,d1.w),d4        ;p2*C2(2)
  2757.     add.w    d4,d4
  2758.     move.w    d4,(4*s,a0)
  2759. s = s+1
  2760.     move.w    d0,d1
  2761.     move.w    d4,d0
  2762.     .fail    s<>28
  2763.     rts
  2764.  
  2765. ;----------------------------------------------------------------
  2766. ;ステレオFilter=3
  2767. ;<d0.w:1つ前のPCMデータ
  2768. ;<d1.w:2つ前のPCMデータ
  2769. ;<a0.l:PCMバッファの位置
  2770. ;<a1.l:Sample(0)のDataの位置
  2771. ;<a2.l:現在のRangeテーブル(11~-1)
  2772. ;    偶数Unitならば下位4bitのみ,奇数Unitならば上位4bitのみを使用し,
  2773. ;    残りのビットを無視するような構造のテーブル
  2774. ;    2*256*13=6656バイト
  2775. ;<a3.l:C1(3)/2テーブルのベース
  2776. ;    ベースはオフセットが0の位置であり,テーブルはベースを挟んで前後に展開される
  2777. ;<a4.l:C2(3)/2テーブルのベース
  2778. ;    ベースはオフセットが0の位置であり,テーブルはベースを挟んで前後に展開される
  2779. ;>d0.w:1つ前のPCMデータ
  2780. ;>d1.w:2つ前のPCMデータ
  2781. ;>a0.l:(変化しない)
  2782. ;?d4
  2783.   .if 1
  2784. ;cdxa_stereo_filter_3はcdxa_stereo_filter_2とまったく同じなので省略
  2785. cdxa_stereo_filter_3    equ    cdxa_stereo_filter_2
  2786.   .else
  2787.     .text
  2788.     .align    4,$2048
  2789. cdxa_stereo_filter_3:
  2790. s = 0
  2791.   .rept 9
  2792.     moveq.l    #0,d4
  2793.     move.b    (4*s,a1),d4        ;Data=$?dまたは$d?
  2794.     add.w    d4,d4
  2795.     move.w    (a2,d4.w),d4        ;d<<(11-Range(u))
  2796.     add.w    (a3,d0.w),d4        ;p1*C1(3)
  2797.     add.w    (a4,d1.w),d4        ;p2*C2(3)
  2798.     add.w    d4,d4
  2799.     move.w    d4,(4*s,a0)
  2800. s = s+1
  2801.     moveq.l    #0,d1
  2802.     move.b    (4*s,a1),d1        ;Data=$?dまたは$d?
  2803.     add.w    d1,d1
  2804.     move.w    (a2,d1.w),d1        ;d<<(11-Range(u))
  2805.     add.w    (a3,d4.w),d1        ;p1*C1(3)
  2806.     add.w    (a4,d0.w),d1        ;p2*C2(3)
  2807.     add.w    d1,d1
  2808.     move.w    d1,(4*s,a0)
  2809. s = s+1
  2810.     moveq.l    #0,d0
  2811.     move.b    (4*s,a1),d0        ;Data=$?dまたは$d?
  2812.     add.w    d0,d0
  2813.     move.w    (a2,d0.w),d0        ;d<<(11-Range(u))
  2814.     add.w    (a3,d1.w),d0        ;p1*C1(3)
  2815.     add.w    (a4,d4.w),d0        ;p2*C2(3)
  2816.     add.w    d0,d0
  2817.     move.w    d0,(4*s,a0)
  2818. s = s+1
  2819.   .endm
  2820.     moveq.l    #0,d4
  2821.     move.b    (4*s,a1),d4        ;Data=$?dまたは$d?
  2822.     add.w    d4,d4
  2823.     move.w    (a2,d4.w),d4        ;d<<(11-Range(u))
  2824.     add.w    (a3,d0.w),d4        ;p1*C1(3)
  2825.     add.w    (a4,d1.w),d4        ;p2*C2(3)
  2826.     add.w    d4,d4
  2827.     move.w    d4,(4*s,a0)
  2828. s = s+1
  2829.     move.w    d0,d1
  2830.     move.w    d4,d0
  2831.     .fail    s<>28
  2832.     rts
  2833.   .endif
  2834.  
  2835. ;----------------------------------------------------------------
  2836. ;----------------------------------------------------------------
  2837. ;高精度モノラルFilter=0
  2838. ;<d0.l:1つ前のPCMデータ<<14
  2839. ;<d1.l:2つ前のPCMデータ<<14
  2840. ;<a0.l:PCMバッファの位置
  2841. ;<a1.l:Sample(0)のDataの位置
  2842. ;<a2.l:現在のRangeテーブル(12~0)
  2843. ;    偶数Unitならば下位4bitのみ,奇数Unitならば上位4bitのみを使用し,
  2844. ;    残りのビットを無視するような構造のテーブル
  2845. ;    4*256*13=13312バイト
  2846. ;>d0.l:1つ前のPCMデータ<<14
  2847. ;>d1.l:2つ前のPCMデータ<<14
  2848. ;>a0.l:(+2*28)
  2849. ;?d5
  2850.     .text
  2851.     .align    4,$2048
  2852. cdxa_mono_filter_0_hq:
  2853.  
  2854. FILTER    .macro    dx
  2855.     moveq.l    #0,dx
  2856.     move.b    (4*s,a1),dx        ;Data=$?dまたは$d?
  2857.     add.w    dx,dx
  2858.     add.w    dx,dx
  2859.     move.l    (a2,dx.w),dx        ;d<<(12-Range(u))
  2860. ;
  2861.     move.l    dx,d5
  2862.   .if 1
  2863.     asl.l    #2,d5
  2864.     swap.w    d5
  2865.   .else
  2866.     asr.l    #8,d5
  2867.   .endif
  2868.     move.w    d5,(a0)+
  2869.     .endm
  2870.  
  2871. s = 0
  2872.   .rept 14
  2873.     FILTER    d1
  2874. s = s+1
  2875.     FILTER    d0
  2876. s = s+1
  2877.   .endm
  2878.     .fail    s<>28
  2879.     rts
  2880.  
  2881. ;----------------------------------------------------------------
  2882. ;高精度モノラルFilter=1
  2883. ;<d0.l:1つ前のPCMデータ<<14
  2884. ;<d1.l:2つ前のPCMデータ<<14
  2885. ;<a0.l:PCMバッファの位置
  2886. ;<a1.l:Sample(0)のDataの位置
  2887. ;<a2.l:現在のRangeテーブル(12~0)
  2888. ;    偶数Unitならば下位4bitのみ,奇数Unitならば上位4bitのみを使用し,
  2889. ;    残りのビットを無視するような構造のテーブル
  2890. ;    4*256*13=13312バイト
  2891. ;>d0.l:1つ前のPCMデータ<<14
  2892. ;>d1.l:2つ前のPCMデータ<<14
  2893. ;>a0.l:(+2*28)
  2894. ;?d5
  2895.     .text
  2896.     .align    4,$2048
  2897. cdxa_mono_filter_1_hq:
  2898.  
  2899. FILTER    .macro    dx,dy
  2900.     moveq.l    #0,dx
  2901.     move.b    (4*s,a1),dx        ;Data=$?dまたは$d?
  2902.     add.w    dx,dx
  2903.     add.w    dx,dx
  2904.     move.l    (a2,dx.w),dx        ;d<<(12-Range(u))
  2905. ;C1(1)=$0000.F000
  2906.     move.l    dy,d5
  2907.     add.l    d5,dx            ;+$0001.0000
  2908.     asr.l    #4,d5            ; $0000.1000
  2909.     sub.l    d5,dx            ;+$0000.F000
  2910. ;
  2911.     move.l    dx,d5
  2912.   .if 1
  2913.     asl.l    #2,d5
  2914.     swap.w    d5
  2915.   .else
  2916.     asr.l    #8,d5
  2917.   .endif
  2918.     move.w    d5,(a0)+
  2919.     .endm
  2920.  
  2921. s = 0
  2922.   .rept 14
  2923.     FILTER    d1,d0
  2924. s = s+1
  2925.     FILTER    d0,d1
  2926. s = s+1
  2927.   .endm
  2928.     .fail    s<>28
  2929.     rts
  2930.  
  2931. ;----------------------------------------------------------------
  2932. ;高精度モノラルFilter=2
  2933. ;<d0.l:1つ前のPCMデータ<<14
  2934. ;<d1.l:2つ前のPCMデータ<<14
  2935. ;<a0.l:PCMバッファの位置
  2936. ;<a1.l:Sample(0)のDataの位置
  2937. ;<a2.l:現在のRangeテーブル(12~0)
  2938. ;    偶数Unitならば下位4bitのみ,奇数Unitならば上位4bitのみを使用し,
  2939. ;    残りのビットを無視するような構造のテーブル
  2940. ;    4*256*13=13312バイト
  2941. ;>d0.l:1つ前のPCMデータ<<14
  2942. ;>d1.l:2つ前のPCMデータ<<14
  2943. ;>a0.l:(+2*28)
  2944. ;?d4-d5
  2945.     .text
  2946.     .align    4,$2048
  2947. cdxa_mono_filter_2_hq:
  2948.  
  2949. FILTER    .macro    dx,dy,dz
  2950.     moveq.l    #0,dx
  2951.     move.b    (4*s,a1),dx        ;Data=$?dまたは$d?
  2952.     add.w    dx,dx
  2953.     add.w    dx,dx
  2954.     move.l    (a2,dx.w),dx        ;d<<(12-Range(u))
  2955. ;C1(2)=$0001.CC00
  2956.     move.l    dy,d5            ; $0001.0000
  2957.     add.l    d5,dx            ;+$0001.0000
  2958.     add.l    d5,dx            ;+$0002.0000
  2959.     asr.l    #2,d5            ; $0000.4000
  2960.     sub.l    d5,dx            ;+$0001.C000
  2961.     asr.l    #2,d5            ; $0000.1000
  2962.     add.l    d5,dx            ;+$0001.D000
  2963.     asr.l    #2,d5            ; $0000.0400
  2964.     sub.l    d5,dx            ;+$0001.CC00
  2965. ;C2(2)=$FFFF.3000=-$0000.D000
  2966.     sub.l    dz,dx            ;-$0001.0000
  2967.     asr.l    #2,dz            ; $0000.4000
  2968.     add.l    dz,dx            ;-$0000.C000
  2969.     asr.l    #2,dz            ; $0000.1000
  2970.     sub.l    dz,dx            ;-$0000.D000
  2971. ;
  2972.     move.l    dx,d5
  2973.   .if 1
  2974.     asl.l    #2,d5
  2975.     swap.w    d5
  2976.   .else
  2977.     asr.l    #8,d5
  2978.   .endif
  2979.     move.w    d5,(a0)+
  2980.     .endm
  2981.  
  2982. s = 0
  2983.   .rept 9
  2984.     FILTER    d4,d0,d1
  2985. s = s+1
  2986.     FILTER    d1,d4,d0
  2987. s = s+1
  2988.     FILTER    d0,d1,d4
  2989. s = s+1
  2990.   .endm
  2991.     FILTER    d4,d0,d1
  2992. s = s+1
  2993.     move.l    d0,d1
  2994.     move.l    d4,d0
  2995.     .fail    s<>28
  2996.     rts
  2997.  
  2998. ;----------------------------------------------------------------
  2999. ;高精度モノラルFilter=3
  3000. ;<d0.l:1つ前のPCMデータ<<14
  3001. ;<d1.l:2つ前のPCMデータ<<14
  3002. ;<a0.l:PCMバッファの位置
  3003. ;<a1.l:Sample(0)のDataの位置
  3004. ;<a2.l:現在のRangeテーブル(12~0)
  3005. ;    偶数Unitならば下位4bitのみ,奇数Unitならば上位4bitのみを使用し,
  3006. ;    残りのビットを無視するような構造のテーブル
  3007. ;    4*256*13=13312バイト
  3008. ;>d0.l:1つ前のPCMデータ<<14
  3009. ;>d1.l:2つ前のPCMデータ<<14
  3010. ;>a0.l:(+2*28)
  3011. ;?d4-d5
  3012.     .text
  3013.     .align    4,$2048
  3014. cdxa_mono_filter_3_hq:
  3015.  
  3016. FILTER    .macro    dx,dy,dz
  3017.     moveq.l    #0,dx
  3018.     move.b    (4*s,a1),dx        ;Data=$?dまたは$d?
  3019.     add.w    dx,dx
  3020.     add.w    dx,dx
  3021.     move.l    (a2,dx.w),dx        ;d<<(12-Range(u))
  3022. ;C1(3)=$0001.8800
  3023.     move.l    dy,d5            ; $0001.0000
  3024.     add.l    d5,dx            ;+$0001.0000
  3025.     asr.l    #1,d5            ; $0000.8000
  3026.     add.l    d5,dx            ;+$0001.8000
  3027.     asr.l    #4,d5            ; $0000.0800
  3028.     add.l    d5,dx            ;+$0001.8800
  3029. ;C2(3)=$FFFF.2400=-$0000.DC00
  3030.     sub.l    dz,dx            ;-$0001.0000
  3031.     asr.l    #3,dz            ; $0000.2000
  3032.     add.l    dz,dx            ;-$0000.E000
  3033.     asr.l    #3,dz            ; $0000.0400
  3034.     add.l    dz,dx            ;-$0000.DC00
  3035. ;
  3036.     move.l    dx,d5
  3037.   .if 1
  3038.     asl.l    #2,d5
  3039.     swap.w    d5
  3040.   .else
  3041.     asr.l    #8,d5
  3042.   .endif
  3043.     move.w    d5,(a0)+
  3044.     .endm
  3045.  
  3046. s = 0
  3047.   .rept 9
  3048.     FILTER    d4,d0,d1
  3049. s = s+1
  3050.     FILTER    d1,d4,d0
  3051. s = s+1
  3052.     FILTER    d0,d1,d4
  3053. s = s+1
  3054.   .endm
  3055.     FILTER    d4,d0,d1
  3056. s = s+1
  3057.     move.l    d0,d1
  3058.     move.l    d4,d0
  3059.     .fail    s<>28
  3060.     rts
  3061.  
  3062. ;----------------------------------------------------------------
  3063. ;----------------------------------------------------------------
  3064. ;高精度ステレオFilter=0
  3065. ;<d0.l:1つ前のPCMデータ<<14
  3066. ;<d1.l:2つ前のPCMデータ<<14
  3067. ;<a0.l:PCMバッファの位置
  3068. ;<a1.l:Sample(0)のDataの位置
  3069. ;<a2.l:現在のRangeテーブル(12~0)
  3070. ;    偶数Unitならば下位4bitのみ,奇数Unitならば上位4bitのみを使用し,
  3071. ;    残りのビットを無視するような構造のテーブル
  3072. ;    4*256*13=13312バイト
  3073. ;>d0.l:1つ前のPCMデータ<<14
  3074. ;>d1.l:2つ前のPCMデータ<<14
  3075. ;>a0.l:(変化しない)
  3076. ;?d5
  3077.     .text
  3078.     .align    4,$2048
  3079. cdxa_stereo_filter_0_hq:
  3080.  
  3081. FILTER    .macro    dx
  3082.     moveq.l    #0,dx
  3083.     move.b    (4*s,a1),dx        ;Data=$?dまたは$d?
  3084.     add.w    dx,dx
  3085.     add.w    dx,dx
  3086.     move.l    (a2,dx.w),dx        ;d<<(12-Range(u))
  3087. ;
  3088.     move.l    dx,d5
  3089.   .if 1
  3090.     asl.l    #2,d5
  3091.     swap.w    d5
  3092.   .else
  3093.     asr.l    #8,d5
  3094.   .endif
  3095.     move.w    d5,(4*s,a0)
  3096.     .endm
  3097.  
  3098. s = 0
  3099.   .rept 14
  3100.     FILTER    d1
  3101. s = s+1
  3102.     FILTER    d0
  3103. s = s+1
  3104.   .endm
  3105.     .fail    s<>28
  3106.     rts
  3107.  
  3108. ;----------------------------------------------------------------
  3109. ;高精度ステレオFilter=1
  3110. ;<d0.l:1つ前のPCMデータ<<14
  3111. ;<d1.l:2つ前のPCMデータ<<14
  3112. ;<a0.l:PCMバッファの位置
  3113. ;<a1.l:Sample(0)のDataの位置
  3114. ;<a2.l:現在のRangeテーブル(12~0)
  3115. ;    偶数Unitならば下位4bitのみ,奇数Unitならば上位4bitのみを使用し,
  3116. ;    残りのビットを無視するような構造のテーブル
  3117. ;    4*256*13=13312バイト
  3118. ;>d0.l:1つ前のPCMデータ<<14
  3119. ;>d1.l:2つ前のPCMデータ<<14
  3120. ;>a0.l:(変化しない)
  3121. ;?d5
  3122.     .text
  3123.     .align    4,$2048
  3124. cdxa_stereo_filter_1_hq:
  3125.  
  3126. FILTER    .macro    dx,dy
  3127.     moveq.l    #0,dx
  3128.     move.b    (4*s,a1),dx        ;Data=$?dまたは$d?
  3129.     add.w    dx,dx
  3130.     add.w    dx,dx
  3131.     move.l    (a2,dx.w),dx        ;d<<(12-Range(u))
  3132. ;C1(1)=$0000.F000
  3133.     move.l    dy,d5
  3134.     add.l    d5,dx            ;+$0001.0000
  3135.     asr.l    #4,d5            ; $0000.1000
  3136.     sub.l    d5,dx            ;+$0000.F000
  3137. ;
  3138.     move.l    dx,d5
  3139.   .if 1
  3140.     asl.l    #2,d5
  3141.     swap.w    d5
  3142.   .else
  3143.     asr.l    #8,d5
  3144.   .endif
  3145.     move.w    d5,(4*s,a0)
  3146.     .endm
  3147.  
  3148. s = 0
  3149.   .rept 14
  3150.     FILTER    d1,d0
  3151. s = s+1
  3152.     FILTER    d0,d1
  3153. s = s+1
  3154.   .endm
  3155.     .fail    s<>28
  3156.     rts
  3157.  
  3158. ;----------------------------------------------------------------
  3159. ;高精度ステレオFilter=2
  3160. ;<d0.l:1つ前のPCMデータ<<14
  3161. ;<d1.l:2つ前のPCMデータ<<14
  3162. ;<a0.l:PCMバッファの位置
  3163. ;<a1.l:Sample(0)のDataの位置
  3164. ;<a2.l:現在のRangeテーブル(12~0)
  3165. ;    偶数Unitならば下位4bitのみ,奇数Unitならば上位4bitのみを使用し,
  3166. ;    残りのビットを無視するような構造のテーブル
  3167. ;    4*256*13=13312バイト
  3168. ;>d0.l:1つ前のPCMデータ<<14
  3169. ;>d1.l:2つ前のPCMデータ<<14
  3170. ;>a0.l:(変化しない)
  3171. ;?d4-d5
  3172.     .text
  3173.     .align    4,$2048
  3174. cdxa_stereo_filter_2_hq:
  3175.  
  3176. FILTER    .macro    dx,dy,dz
  3177.     moveq.l    #0,dx
  3178.     move.b    (4*s,a1),dx        ;Data=$?dまたは$d?
  3179.     add.w    dx,dx
  3180.     add.w    dx,dx
  3181.     move.l    (a2,dx.w),dx        ;d<<(12-Range(u))
  3182. ;C1(2)=$0001.CC00
  3183.     move.l    dy,d5            ; $0001.0000
  3184.     add.l    d5,dx            ;+$0001.0000
  3185.     add.l    d5,dx            ;+$0002.0000
  3186.     asr.l    #2,d5            ; $0000.4000
  3187.     sub.l    d5,dx            ;+$0001.C000
  3188.     asr.l    #2,d5            ; $0000.1000
  3189.     add.l    d5,dx            ;+$0001.D000
  3190.     asr.l    #2,d5            ; $0000.0400
  3191.     sub.l    d5,dx            ;+$0001.CC00
  3192. ;C2(2)=$FFFF.3000=-$0000.D000
  3193.     sub.l    dz,dx            ;-$0001.0000
  3194.     asr.l    #2,dz            ; $0000.4000
  3195.     add.l    dz,dx            ;-$0000.C000
  3196.     asr.l    #2,dz            ; $0000.1000
  3197.     sub.l    dz,dx            ;-$0000.D000
  3198. ;
  3199.     move.l    dx,d5
  3200.   .if 1
  3201.     asl.l    #2,d5
  3202.     swap.w    d5
  3203.   .else
  3204.     asr.l    #8,d5
  3205.   .endif
  3206.     move.w    d5,(4*s,a0)
  3207.     .endm
  3208.  
  3209. s = 0
  3210.   .rept 9
  3211.     FILTER    d4,d0,d1
  3212. s = s+1
  3213.     FILTER    d1,d4,d0
  3214. s = s+1
  3215.     FILTER    d0,d1,d4
  3216. s = s+1
  3217.   .endm
  3218.     FILTER    d4,d0,d1
  3219. s = s+1
  3220.     move.l    d0,d1
  3221.     move.l    d4,d0
  3222.     .fail    s<>28
  3223.     rts
  3224.  
  3225. ;----------------------------------------------------------------
  3226. ;高精度ステレオFilter=3
  3227. ;<d0.l:1つ前のPCMデータ<<14
  3228. ;<d1.l:2つ前のPCMデータ<<14
  3229. ;<a0.l:PCMバッファの位置
  3230. ;<a1.l:Sample(0)のDataの位置
  3231. ;<a2.l:現在のRangeテーブル(12~0)
  3232. ;    偶数Unitならば下位4bitのみ,奇数Unitならば上位4bitのみを使用し,
  3233. ;    残りのビットを無視するような構造のテーブル
  3234. ;    4*256*13=13312バイト
  3235. ;>d0.l:1つ前のPCMデータ<<14
  3236. ;>d1.l:2つ前のPCMデータ<<14
  3237. ;>a0.l:(変化しない)
  3238. ;?d4-d5
  3239.     .text
  3240.     .align    4,$2048
  3241. cdxa_stereo_filter_3_hq:
  3242.  
  3243. FILTER    .macro    dx,dy,dz
  3244.     moveq.l    #0,dx
  3245.     move.b    (4*s,a1),dx        ;Data=$?dまたは$d?
  3246.     add.w    dx,dx
  3247.     add.w    dx,dx
  3248.     move.l    (a2,dx.w),dx        ;d<<(12-Range(u))
  3249. ;C1(3)=$0001.8800
  3250.     move.l    dy,d5            ; $0001.0000
  3251.     add.l    d5,dx            ;+$0001.0000
  3252.     asr.l    #1,d5            ; $0000.8000
  3253.     add.l    d5,dx            ;+$0001.8000
  3254.     asr.l    #4,d5            ; $0000.0800
  3255.     add.l    d5,dx            ;+$0001.8800
  3256. ;C2(3)=$FFFF.2400=-$0000.DC00
  3257.     sub.l    dz,dx            ;-$0001.0000
  3258.     asr.l    #3,dz            ; $0000.2000
  3259.     add.l    dz,dx            ;-$0000.E000
  3260.     asr.l    #3,dz            ; $0000.0400
  3261.     add.l    dz,dx            ;-$0000.DC00
  3262. ;
  3263.     move.l    dx,d5
  3264.   .if 1
  3265.     asl.l    #2,d5
  3266.     swap.w    d5
  3267.   .else
  3268.     asr.l    #8,d5
  3269.   .endif
  3270.     move.w    d5,(4*s,a0)
  3271.     .endm
  3272.  
  3273. s = 0
  3274.   .rept 9
  3275.     FILTER    d4,d0,d1
  3276. s = s+1
  3277.     FILTER    d1,d4,d0
  3278. s = s+1
  3279.     FILTER    d0,d1,d4
  3280. s = s+1
  3281.   .endm
  3282.     FILTER    d4,d0,d1
  3283. s = s+1
  3284.     move.l    d0,d1
  3285.     move.l    d4,d0
  3286.     .fail    s<>28
  3287.     rts
  3288.  
  3289. ;----------------------------------------------------------------
  3290.     .data
  3291. cdxa_tables_constructed:    .dc.b    0    ;-1=テーブルが初期化された
  3292.  
  3293.     .bss
  3294.     .align    4
  3295. even_range_table_ptr:    .ds.l    1    ;偶数Unit用のRangeテーブルの先頭
  3296. odd_range_table_ptr:    .ds.l    1    ;奇数Unit用のRangeテーブルの先頭
  3297. hq_even_range_table_ptr:    .ds.l    1    ;高精度偶数Unit用のRangeテーブルの先頭
  3298. hq_odd_range_table_ptr:        .ds.l    1    ;高精度奇数Unit用のRangeテーブルの先頭
  3299. c1_1_table_base_ptr:    .ds.l    1    ;C1(1)/2テーブルのベース
  3300. c1_2_table_base_ptr:    .ds.l    1    ;C1(2)/2テーブルのベース
  3301. c1_3_table_base_ptr:    .ds.l    1    ;C1(3)/2テーブルのベース
  3302. c2_2_table_base_ptr:    .ds.l    1    ;C2(2)/2テーブルのベース
  3303. c2_3_table_base_ptr:    .ds.l    1    ;C2(3)/2テーブルのベース
  3304. mono_even_filter_table_ptr:    .ds.l    1    ;偶数Unit用Filterテーブルの先頭
  3305. mono_odd_filter_table_ptr:    .ds.l    1    ;奇数Unit用Filterテーブルの先頭
  3306. stereo_even_filter_table_ptr:    .ds.l    1    ;偶数Unit(left)用Filterテーブルの先頭
  3307. stereo_odd_filter_table_ptr:    .ds.l    1    ;奇数Unit(right)用Filterテーブルの先頭
  3308. hq_mono_even_filter_table_ptr:        .ds.l    1    ;高精度偶数Unit用Filterテーブルの先頭
  3309. hq_mono_odd_filter_table_ptr:        .ds.l    1    ;高精度奇数Unit用Filterテーブルの先頭
  3310. hq_stereo_even_filter_table_ptr:    .ds.l    1    ;高精度偶数Unit(left)用Filterテーブルの先頭
  3311. hq_stereo_odd_filter_table_ptr:        .ds.l    1    ;高精度奇数Unit(right)用Filterテーブルの先頭
  3312.  
  3313. ;----------------------------------------------------------------
  3314. ;----------------------------------------------------------------
  3315. ;xxデータの前処理(xxデータをOPMのTLの並びに変換する)
  3316. ;<a0.l:出力バッファの先頭
  3317. ;<a1.l:入力データの先頭(該当するセクタの先頭)
  3318. ;<a2.l:入力データの末尾+1
  3319. ;>a0.l:出力データの末尾+1
  3320. ;>a1.l:出力データの先頭
  3321. ;?d1-d7/a2-a6
  3322.     .text
  3323.  
  3324. ;モノラル→モノラル
  3325. START_PRECONV_BUFFER    .macro    side
  3326.     lea.l    xx2pcm_buffer,Asrc
  3327.     move.l    d0,-(sp)
  3328.     movem.l    a0-a2,-(sp)
  3329.     movea.l    Asrc,a0
  3330.     movea.l    xx2pcm_src_top_ptr,a1
  3331.     move.l    xx2pcm_src_lim_ptr,d0
  3332.     lea.l    (2048,a1),a2
  3333.     cmpa.l    d0,a2
  3334.     bls    @f
  3335.     movea.l    d0,a2
  3336. @@:    bsr    decode_xx_mono
  3337.     move.l    a1,xx2pcm_src_cur_ptr
  3338.     move.l    a0,d0
  3339.     movem.l    (sp)+,a0-a2
  3340.     movea.l    d0,Alim
  3341.     move.l    (sp)+,d0
  3342.     movea.l    xx2pcm_dst_top_ptr,Adst
  3343.     .endm
  3344.  
  3345. LOOP_PRECONV_BUFFER    .macro    side
  3346.     lea.l    xx2pcm_buffer,Asrc
  3347.     move.l    d0,-(sp)
  3348.     movem.l    a0-a2,-(sp)
  3349.     movea.l    Asrc,a0
  3350.     movea.l    xx2pcm_src_cur_ptr,a1
  3351.     move.l    xx2pcm_src_lim_ptr,d0
  3352.     lea.l    (2048,a1),a2
  3353.     cmpa.l    d0,a2
  3354.     bls    @f
  3355.     movea.l    d0,a2
  3356. @@:    bsr    decode_xx_mono
  3357.     move.l    a1,xx2pcm_src_cur_ptr
  3358.     move.l    a0,d0
  3359.     movem.l    (sp)+,a0-a2
  3360.     movea.l    d0,Alim
  3361.     move.l    (sp)+,d0
  3362.     cmpa.l    Alim,Asrc
  3363.     bhs    @f
  3364.     jmp    (Ajmp)
  3365. @@:
  3366.     .endm
  3367.  
  3368. GET_DATA_0    .macro    src,dat,tmp
  3369.     move.w    (src)+,dat
  3370.     .endm
  3371.  
  3372.   .irp %q,LQ,HQ,SQ
  3373.     .align    4,$2048
  3374. preconv_sxx4_stereo_%q::
  3375. preconv_mxx4_mono_%q::
  3376. preconv_sxx4_mono_%q::
  3377.     move.l    a0,xx2pcm_dst_top_ptr
  3378.     move.l    a1,xx2pcm_src_top_ptr
  3379.     move.l    a1,xx2pcm_src_cur_ptr
  3380.     move.l    a2,xx2pcm_src_lim_ptr
  3381.     PRECONV_MONO_%q
  3382.     movea.l    xx2pcm_dst_top_ptr,a1
  3383.     rts
  3384.   .endm
  3385.  
  3386.     .bss
  3387.     .align    4
  3388. xx2pcm_dst_top_ptr:    .ds.l    1
  3389. xx2pcm_src_top_ptr:    .ds.l    1
  3390. xx2pcm_src_cur_ptr:    .ds.l    1
  3391. xx2pcm_src_lim_ptr:    .ds.l    1
  3392. xx2pcm_buffer:        .ds.b    7168    ;2048/16*28*2=7168
  3393.  
  3394. ;----------------------------------------------------------------
  3395. ;xxデータのデコード(モノラル)
  3396. ;<a0.l:PCMバッファの先頭
  3397. ;<a1.l:xxデータの先頭
  3398. ;<a2.l:xxデータの末尾+1
  3399. ;    xxデータのサイズは16の倍数にすること
  3400. ;>a0.l:PCMデータの末尾+1
  3401. ;>a1.l:xxデータの末尾+1
  3402.     .text
  3403.     .align    4,$2048
  3404. decode_xx_mono:
  3405.     movem.l    d0-d7/a3,-(sp)
  3406.  
  3407.     move.l    left1,d3        ;1つ前
  3408.     move.l    left2,d4        ;2つ前
  3409.  
  3410.     bra    19f
  3411.  
  3412. 10:
  3413.     moveq.l    #0,d0
  3414.     move.b    (a1)+,d0        ;Filter,Range
  3415.     cmpi.b    #$07,(a1)+
  3416.     bne    2f
  3417.     moveq.l    #0,d1
  3418.   .rept 28/2
  3419.     move.l    d1,(a0)+
  3420.   .endm
  3421.     lea.l    (-1-1+16,a1),a1
  3422.     bra    19f
  3423. 2:
  3424.  
  3425.     moveq.l    #$0F,d2
  3426.     and.w    d0,d2            ;Range
  3427.     sub.w    d2,d0            ;Filter<<4
  3428.     addq.w    #4,d2            ;Range+4
  3429.     lsr.w    #2,d0            ;Filter<<2
  3430.     lea.l    xx_table,a3
  3431.     adda.l    d0,a3
  3432.     move.w    (a3)+,d6        ;C1(f)
  3433.     move.w    (a3)+,d7        ;C2(f)
  3434.  
  3435. FILTER    .macro    t,dx,dy,dz
  3436.   .if t=0
  3437.     moveq.l    #$0F,dx
  3438.     and.b    (a1),dx
  3439.   .else
  3440.     moveq.l    #0,dx
  3441.     move.b    (a1)+,dx
  3442.     lsr.b    #4,dx
  3443.   .endif
  3444.     ror.l    #4,dx
  3445.     asr.l    d2,dx            ;d<<(28-(Range+4))=d<<(12-Range+12)
  3446.  
  3447.     movea.l    dy,a3
  3448.     move.l    dy,d0
  3449.     bpl    @f
  3450.     neg.l    d0
  3451. @@:    move.l    d0,d1
  3452.                 ;   d0       d1
  3453.     mulu.w    d6,d0        ; mid|low
  3454.     swap.w    d1        ; mid|low
  3455.     mulu.w    d6,d1        ; mid|low  high|mid  highは最大6ビット
  3456.     swap.w    d0        ; low|mid  high|mid
  3457.     add.w    d0,d1        ; low| ?   high|mid  x=midの繰り上がり
  3458.     clr.w    d0        ; low| 0   high|mid  x=midの繰り上がり
  3459.     swap.w    d1        ; low| 0   mid|high  x=midの繰り上がり
  3460.     addx.w    d0,d1        ; low| 0   mid|high  low,mid,highとも確定
  3461.     swap.w    d0        ;  0 |low  mid|high
  3462.     and.w    #-64,d0        ;  0 |low  mid|high  lowの下位6ビットを切り捨てる
  3463.     or.l    d1,d0        ; mid|low|high
  3464.     ror.l    #6,d0        ; high|mid|low
  3465.     move.l    a3,d1
  3466.     bpl    @f
  3467.     neg.l    d0
  3468. @@:
  3469.     add.l    d0,dx            ;1つ前×C1(f)
  3470.  
  3471.     movea.l    dz,a3
  3472.     move.l    dz,d0
  3473.     bpl    @f
  3474.     neg.l    d0
  3475. @@:    move.l    d0,d1
  3476.                 ;   d0       d1
  3477.     mulu.w    d7,d0        ; mid|low
  3478.     swap.w    d1        ; mid|low
  3479.     mulu.w    d7,d1        ; mid|low  high|mid  highは最大6ビット
  3480.     swap.w    d0        ; low|mid  high|mid
  3481.     add.w    d0,d1        ; low| ?   high|mid  x=midの繰り上がり
  3482.     clr.w    d0        ; low| 0   high|mid  x=midの繰り上がり
  3483.     swap.w    d1        ; low| 0   mid|high  x=midの繰り上がり
  3484.     addx.w    d0,d1        ; low| 0   mid|high  low,mid,highとも確定
  3485.     swap.w    d0        ;  0 |low  mid|high
  3486.     and.w    #-64,d0        ;  0 |low  mid|high  lowの下位6ビットを切り捨てる
  3487.     or.l    d1,d0        ; mid|low|high
  3488.     ror.l    #6,d0        ; high|mid|low
  3489.     move.l    a3,d1
  3490.     bpl    @f
  3491.     neg.l    d0
  3492. @@:
  3493.     sub.l    d0,dx            ;2つ前×C2(f)
  3494.  
  3495.     move.l    dx,d0
  3496.     asl.l    #4,d0
  3497.     swap.w    d0
  3498.     move.w    d0,(a0)+
  3499.     .endm
  3500.  
  3501.   .rept 4
  3502.     FILTER    0,d5,d3,d4
  3503.     FILTER    1,d4,d5,d3
  3504.     FILTER    0,d3,d4,d5
  3505.     FILTER    1,d5,d3,d4
  3506.     FILTER    0,d4,d5,d3
  3507.     FILTER    1,d3,d4,d5
  3508.   .endm
  3509.     FILTER    0,d5,d3,d4
  3510.     FILTER    1,d4,d5,d3
  3511.     FILTER    0,d3,d4,d5
  3512.     FILTER    1,d5,d3,d4
  3513.  
  3514.     move.l    d3,d4
  3515.     move.l    d5,d3
  3516.  
  3517. 19:    cmpa.l    a2,a1
  3518.     blo    10b
  3519.  
  3520.     move.l    d3,left1        ;1つ前
  3521.     move.l    d4,left2        ;2つ前
  3522.  
  3523.     movem.l    (sp)+,d0-d7/a3
  3524.     rts
  3525.  
  3526.     .data
  3527.     .align    4
  3528. xx_table::    .dcb.w    2*16,255    ;C1(f),-C2(f)
  3529.